github.com/cbeuw/gotfo@v0.0.0-20180331191851-f2b091af84de/util.go (about) 1 package gotfo 2 3 import ( 4 "context" 5 "errors" 6 "net" 7 "syscall" 8 "time" 9 "unsafe" 10 ) 11 12 var ( 13 errTimeout = errors.New("operation timed out") 14 errCanceled = errors.New("operation was canceled") 15 errClosing = errors.New("use of closed network connection") 16 aLongTimeAgo = time.Unix(1, 0) 17 noDeadline = time.Time{} 18 ) 19 20 type conn struct { 21 fd *netFD 22 } 23 24 type TCPConn struct { 25 conn 26 } 27 28 type TCPListener struct { 29 fd *netFD 30 } 31 32 // ipv4 only 33 func sockaddrToTCPAddr(sa syscall.Sockaddr) net.Addr { 34 addr := sa.(*syscall.SockaddrInet4) 35 return &net.TCPAddr{IP: addr.Addr[0:], Port: addr.Port} 36 } 37 38 // ipv4 only 39 func tcpAddrToSockaddr(addr *net.TCPAddr) syscall.Sockaddr { 40 sa := &syscall.SockaddrInet4{Port: addr.Port} 41 copy(sa.Addr[:], addr.IP.To4()) 42 return sa 43 } 44 45 func mapErr(err error) error { 46 switch err { 47 case context.Canceled: 48 return errCanceled 49 case context.DeadlineExceeded: 50 return errTimeout 51 default: 52 return err 53 } 54 } 55 56 func newTCPConn(fd *netFD) *net.TCPConn { 57 dummyConn := &TCPConn{} 58 dummyConn.conn.fd = fd 59 60 if fd.incref() == nil { 61 syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, 1) 62 fd.decref() 63 } 64 65 conn := (*net.TCPConn)(unsafe.Pointer(dummyConn)) 66 67 return conn 68 } 69 70 func newTCPListener(fd *netFD, returnWrapper bool) net.Listener { 71 dummyListener := &TCPListener{} 72 dummyListener.fd = fd 73 74 listener := (*net.TCPListener)(unsafe.Pointer(dummyListener)) 75 76 if returnWrapper { 77 return &TFOListener{listener, fd} 78 } 79 80 return listener 81 }