From abd8b69979eb846dc12b6b7bcea51aebdf8065f4 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 14 Dec 2018 18:15:35 -0600 Subject: [PATCH] send a switch message immediately when peering, and use OS-level TCP keep-alive (shouldn't matter right now, since we have application-level keep-alive that preempts it, but important later) --- src/yggdrasil/peer.go | 9 ++++----- src/yggdrasil/tcp.go | 24 +++++++++++++++--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/yggdrasil/peer.go b/src/yggdrasil/peer.go index 67aa805a..e092513b 100644 --- a/src/yggdrasil/peer.go +++ b/src/yggdrasil/peer.go @@ -177,6 +177,7 @@ func (p *peer) doSendSwitchMsgs() { func (p *peer) linkLoop() { tick := time.NewTicker(time.Second) defer tick.Stop() + p.doSendSwitchMsgs() for { select { case _, ok := <-p.doSend: @@ -185,11 +186,9 @@ func (p *peer) linkLoop() { } p.sendSwitchMsg() case _ = <-tick.C: - //break // FIXME disabled the below completely to test something - pdinfo := p.dinfo // FIXME this is a bad workarond NPE on the next line - if pdinfo != nil { - dinfo := *pdinfo - p.core.dht.peers <- &dinfo + dinfo := p.dinfo // FIXME? are pointer reads *always* atomic? + if dinfo != nil { + p.core.dht.peers <- dinfo } } } diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go index 5ca66304..5d4bfc71 100644 --- a/src/yggdrasil/tcp.go +++ b/src/yggdrasil/tcp.go @@ -31,14 +31,6 @@ const tcp_msgSize = 2048 + 65535 // TODO figure out what makes sense const default_tcp_timeout = 6 * time.Second const tcp_ping_interval = (default_tcp_timeout * 2 / 3) -// Wrapper function for non tcp/ip connections. -func setNoDelay(c net.Conn, delay bool) { - tcp, ok := c.(*net.TCPConn) - if ok { - tcp.SetNoDelay(delay) - } -} - // The TCP listener and information about active TCP connections, to avoid duplication. type tcpInterface struct { core *Core @@ -58,6 +50,20 @@ type tcpInfo struct { remoteAddr string } +// Wrapper function to set additional options for specific connection types. +func (iface *tcpInterface) setExtraOptions(c net.Conn) { + switch sock := c.(type) { + case *net.TCPConn: + sock.SetNoDelay(true) + sock.SetKeepAlive(true) + sock.SetKeepAlivePeriod(iface.tcp_timeout) + panic("DEBUG testing") + // TODO something for socks5 + default: + iface.core.log.Println("Unrecognized connection type: %v", sock) + } +} + // Returns the address of the listener. func (iface *tcpInterface) getAddr() *net.TCPAddr { return iface.serv.Addr().(*net.TCPAddr) @@ -205,6 +211,7 @@ func (iface *tcpInterface) call(saddr string, socksaddr *string, sintf string) { // It defers a bunch of cleanup stuff to tear down all of these things when the reader exists (e.g. due to a closed connection or a timeout). func (iface *tcpInterface) handler(sock net.Conn, incoming bool) { defer sock.Close() + iface.setExtraOptions(sock) // Get our keys myLinkPub, myLinkPriv := newBoxKeys() // ephemeral link keys meta := version_getBaseMetadata() @@ -342,7 +349,6 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) { out <- msg } p.close = func() { sock.Close() } - setNoDelay(sock, true) go p.linkLoop() defer func() { // Put all of our cleanup here...