From f7a7f601a0938ecd5d0bf8316120865bebd69932 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 14 Jun 2018 08:38:43 -0500 Subject: [PATCH 1/4] cleanup old ugly session MTU code that only mattered with lossy UDP fragments --- src/yggdrasil/session.go | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index 2580f45d..b36349ac 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -437,41 +437,14 @@ func (sinfo *sessionInfo) doSend(bs []byte) { // TODO? remove the MTU updating part? That should never happen with TCP peers, and the old UDP code that caused it was removed (and if replaced, should be replaced with something that can reliably send messages with an arbitrary size). func (sinfo *sessionInfo) doRecv(p *wire_trafficPacket) { defer util_putBytes(p.Payload) - payloadSize := uint16(len(p.Payload)) if !sinfo.nonceIsOK(&p.Nonce) { return } bs, isOK := boxOpen(&sinfo.sharedSesKey, p.Payload, &p.Nonce) if !isOK { - // We're going to guess that the session MTU is too large - // Set myMTU to the largest value we think we can receive - fixSessionMTU := func() { - // This clamps down to 1280 almost immediately over ipv4 - // Over link-local ipv6, it seems to approach link MTU - // So maybe it's doing the right thing?... - //sinfo.core.log.Println("DEBUG got bad packet:", payloadSize) - newMTU := payloadSize - boxOverhead - if newMTU < 1280 { - newMTU = 1280 - } - if newMTU < sinfo.myMTU { - sinfo.myMTU = newMTU - sinfo.core.sessions.sendPingPong(sinfo, false) - sinfo.mtuTime = time.Now() - sinfo.wasMTUFixed = true - } - } - go func() { sinfo.core.router.admin <- fixSessionMTU }() util_putBytes(bs) return } - fixSessionMTU := func() { - if time.Since(sinfo.mtuTime) > time.Minute { - sinfo.myMTU = uint16(sinfo.core.tun.mtu) - sinfo.mtuTime = time.Now() - } - } - go func() { sinfo.core.router.admin <- fixSessionMTU }() sinfo.updateNonce(&p.Nonce) sinfo.time = time.Now() sinfo.bytesRecvd += uint64(len(bs)) From 57837057b7874741f9e6ff829fb197b27fd6541b Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 14 Jun 2018 09:11:34 -0500 Subject: [PATCH 2/4] tcp/socks cleanup --- src/yggdrasil/tcp.go | 66 +++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go index 9590f221..a768ec70 100644 --- a/src/yggdrasil/tcp.go +++ b/src/yggdrasil/tcp.go @@ -60,28 +60,17 @@ func (iface *tcpInterface) getAddr() *net.TCPAddr { // Attempts to initiate a connection to the provided address. func (iface *tcpInterface) connect(addr string) { - iface.call(addr) + iface.call(addr, nil) } // Attempst to initiate a connection to the provided address, viathe provided socks proxy address. func (iface *tcpInterface) connectSOCKS(socksaddr, peeraddr string) { - // TODO make sure this doesn't keep attempting/killing connections when one is already active. - // I think some of the interaction between this and callWithConn needs work, so the dial isn't even attempted if there's already an outgoing call to peeraddr. - // Or maybe only if there's already an outgoing call to peeraddr via this socksaddr? go func() { dialer, err := proxy.SOCKS5("tcp", socksaddr, nil, proxy.Direct) - if err == nil { - conn, err := dialer.Dial("tcp", peeraddr) - if err == nil { - iface.callWithConn(&wrappedConn{ - c: conn, - raddr: &wrappedAddr{ - network: "tcp", - addr: peeraddr, - }, - }) - } + if err != nil { + return } + iface.call(peeraddr, dialer) }() } @@ -112,33 +101,12 @@ func (iface *tcpInterface) listener() { } } -// Called by connectSOCKS, it's like call but with the connection already established. -func (iface *tcpInterface) callWithConn(conn net.Conn) { - go func() { - raddr := conn.RemoteAddr().String() - iface.mutex.Lock() - _, isIn := iface.calls[raddr] - iface.mutex.Unlock() - if !isIn { - iface.mutex.Lock() - iface.calls[raddr] = struct{}{} - iface.mutex.Unlock() - defer func() { - iface.mutex.Lock() - delete(iface.calls, raddr) - iface.mutex.Unlock() - }() - iface.handler(conn, false) - } - }() -} - // Checks if a connection already exists. // If not, it adds it to the list of active outgoing calls (to block future attempts) and dials the address. // If the dial is successful, it launches the handler. // When finished, it removes the outgoing call, so reconnection attempts can be made later. // This all happens in a separate goroutine that it spawns. -func (iface *tcpInterface) call(saddr string) { +func (iface *tcpInterface) call(saddr string, dialer proxy.Dialer) { go func() { quit := false iface.mutex.Lock() @@ -153,13 +121,31 @@ func (iface *tcpInterface) call(saddr string) { }() } iface.mutex.Unlock() - if !quit { - conn, err := net.Dial("tcp", saddr) + if quit { + return + } + var conn net.Conn + var err error + if dialer != nil { + conn, err = dialer.Dial("tcp", saddr) + if err != nil { + return + } + // + conn = &wrappedConn{ + c: conn, + raddr: &wrappedAddr{ + network: "tcp", + addr: saddr, + }, + } + } else { + conn, err = net.Dial("tcp", saddr) if err != nil { return } - iface.handler(conn, false) } + iface.handler(conn, false) }() } From e8eaabf0c8d2aa80d012f870ff0c592947236c3f Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 14 Jun 2018 09:12:58 -0500 Subject: [PATCH 3/4] comment --- src/yggdrasil/tcp.go | 1 - 1 file changed, 1 deletion(-) diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go index a768ec70..e70507f2 100644 --- a/src/yggdrasil/tcp.go +++ b/src/yggdrasil/tcp.go @@ -131,7 +131,6 @@ func (iface *tcpInterface) call(saddr string, dialer proxy.Dialer) { if err != nil { return } - // conn = &wrappedConn{ c: conn, raddr: &wrappedAddr{ From d9c97876110c7a62f70add6172a51ff88b1e4da4 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 14 Jun 2018 09:21:35 -0500 Subject: [PATCH 4/4] avoid the proxy.SOCK5 connection attempt unless we're actually going to use the dialer --- src/yggdrasil/tcp.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go index e70507f2..48695419 100644 --- a/src/yggdrasil/tcp.go +++ b/src/yggdrasil/tcp.go @@ -65,13 +65,7 @@ func (iface *tcpInterface) connect(addr string) { // Attempst to initiate a connection to the provided address, viathe provided socks proxy address. func (iface *tcpInterface) connectSOCKS(socksaddr, peeraddr string) { - go func() { - dialer, err := proxy.SOCKS5("tcp", socksaddr, nil, proxy.Direct) - if err != nil { - return - } - iface.call(peeraddr, dialer) - }() + iface.call(peeraddr, &socksaddr) } // Initializes the struct. @@ -106,7 +100,7 @@ func (iface *tcpInterface) listener() { // If the dial is successful, it launches the handler. // When finished, it removes the outgoing call, so reconnection attempts can be made later. // This all happens in a separate goroutine that it spawns. -func (iface *tcpInterface) call(saddr string, dialer proxy.Dialer) { +func (iface *tcpInterface) call(saddr string, socksaddr *string) { go func() { quit := false iface.mutex.Lock() @@ -126,7 +120,12 @@ func (iface *tcpInterface) call(saddr string, dialer proxy.Dialer) { } var conn net.Conn var err error - if dialer != nil { + if socksaddr != nil { + var dialer proxy.Dialer + dialer, err = proxy.SOCKS5("tcp", *socksaddr, nil, proxy.Direct) + if err != nil { + return + } conn, err = dialer.Dial("tcp", saddr) if err != nil { return