This commit is contained in:
Neil Alexander 2018-10-09 16:25:53 +00:00 committed by GitHub
commit 7261c8ce9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 3 deletions

View file

@ -7,6 +7,7 @@ type NodeConfig struct {
Peers []string `comment:"List of connection strings for static peers in URI format, i.e.\ntcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j."`
InterfacePeers map[string][]string `comment:"List of connection strings for static peers in URI format, arranged\nby source interface, i.e. { \"eth0\": [ tcp://a.b.c.d:e ] }. Note that\nSOCKS peerings will NOT be affected by this option and should go in\nthe \"Peers\" section instead."`
ReadTimeout int32 `comment:"Read timeout for connections, specified in milliseconds. If less\nthan 6000 and not negative, 6000 (the default) is used. If negative,\nreads won't time out."`
DSCPClassification uint8 `comment:"DSCP classification, in decimal, for applying Quality of Service\n(QoS) markings to outbound peering traffic. This value will more\nthan likely be ignored if peering over the Internet."`
AllowedEncryptionPublicKeys []string `comment:"List of peer encryption public keys to allow or incoming TCP\nconnections from. If left empty/undefined then all connections\nwill be allowed by default."`
EncryptionPublicKey string `comment:"Your public encryption key. Your peers may ask you for this to put\ninto their AllowedEncryptionPublicKeys configuration."`
EncryptionPrivateKey string `comment:"Your private encryption key. DO NOT share this with anyone!"`

View file

@ -97,7 +97,7 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
c.init(&boxPub, &boxPriv, &sigPub, &sigPriv)
c.admin.init(c, nc.AdminListen)
if err := c.tcp.init(c, nc.Listen, nc.ReadTimeout); err != nil {
if err := c.tcp.init(c, nc.Listen, nc.ReadTimeout, nc.DSCPClassification); err != nil {
c.log.Println("Failed to start TCP interface")
return err
}

View file

@ -427,7 +427,7 @@ func (c *Core) DEBUG_addSOCKSConn(socksaddr, peeraddr string) {
//*
func (c *Core) DEBUG_setupAndStartGlobalTCPInterface(addrport string) {
if err := c.tcp.init(c, addrport, 0); err != nil {
if err := c.tcp.init(c, addrport, 0, 0); err != nil {
c.log.Println("Failed to start TCP interface:", err)
panic(err)
}

View file

@ -24,6 +24,8 @@ import (
"sync/atomic"
"time"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"golang.org/x/net/proxy"
)
@ -47,6 +49,7 @@ type tcpInterface struct {
mutex sync.Mutex // Protecting the below
calls map[string]struct{}
conns map[tcpInfo](chan struct{})
dscp uint8
}
// This is used as the key to a map that tracks existing connections, to prevent multiple connections to the same keys and local/remote address pair from occuring.
@ -74,9 +77,14 @@ func (iface *tcpInterface) connectSOCKS(socksaddr, peeraddr string) {
}
// Initializes the struct.
func (iface *tcpInterface) init(core *Core, addr string, readTimeout int32) (err error) {
func (iface *tcpInterface) init(core *Core, addr string, readTimeout int32, dscp uint8) (err error) {
iface.core = core
// The DSCP value is 6-bit
if dscp >= 0 && dscp <= 63 {
iface.dscp = dscp
}
iface.tcp_timeout = time.Duration(readTimeout) * time.Millisecond
if iface.tcp_timeout >= 0 && iface.tcp_timeout < default_tcp_timeout {
iface.tcp_timeout = default_tcp_timeout
@ -197,6 +205,19 @@ func (iface *tcpInterface) call(saddr string, socksaddr *string, sintf string) {
return
}
}
// Configure DSCP on the connection, if set
if iface.dscp != 0 {
addr := conn.RemoteAddr().(*net.TCPAddr)
if addr.IP.To16() != nil && addr.IP.To4() == nil {
if err := ipv6.NewConn(conn).SetTrafficClass(int(iface.dscp << 2)); err != nil {
iface.core.log.Println("Failed to set traffic class:", err)
}
} else {
if err := ipv4.NewConn(conn).SetTOS(int(iface.dscp << 2)); err != nil {
iface.core.log.Println("Failed to set TOS:", err)
}
}
}
iface.handler(conn, false)
}()
}
@ -223,6 +244,19 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) {
if err != nil {
return
}
// Configure DSCP on the connection, if set
if iface.dscp != 0 {
addr := sock.RemoteAddr().(*net.TCPAddr)
if addr.IP.To16() != nil && addr.IP.To4() == nil {
if err := ipv6.NewConn(sock).SetTrafficClass(int(iface.dscp << 2)); err != nil {
iface.core.log.Println("Failed to set traffic class:", err)
}
} else {
if err := ipv4.NewConn(sock).SetTOS(int(iface.dscp << 2)); err != nil {
iface.core.log.Println("Failed to set TOS:", err)
}
}
}
meta = version_metadata{} // Reset to zero value
if !meta.decode(metaBytes) || !meta.check() {
// Failed to decode and check the metadata