//network is useless ,it will always use tcp4 func TfoListen(network string, listenAddr string) (listener net.Listener, err error) { s, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, 0) if err != nil { return nil, err } defer unix.Close(s) err = unix.SetsockoptInt(s, unix.SOL_TCP, 23, 10) if err != nil { return nil, err } err = unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) if err != nil { return nil, err } sa, err := kmgUnix.IPv4TcpAddrToUnixSocksAddr(listenAddr) if err != nil { return nil, err } err = unix.Bind(s, sa) if err != nil { return nil, err } err = unix.Listen(s, 10) if err != nil { return nil, err } f := os.NewFile(uintptr(s), "TFOListen") defer f.Close() return net.FileListener(f) }
// TcpListen is listening for incoming IP packets which are being intercepted. // In conflict to regular Listen mehtod the socket destination and source addresses // are of the intercepted connection. // Else then that it works exactly like net package net.Listen. func TcpListen(listenAddr string) (listener net.Listener, err error) { s, err := unix.Socket(unix.AF_INET6, unix.SOCK_STREAM, 0) if err != nil { return nil, err } defer unix.Close(s) err = unix.SetsockoptInt(s, unix.SOL_IP, unix.IP_TRANSPARENT, 1) if err != nil { return nil, err } sa, err := IPv6TcpAddrToUnixSocksAddr(listenAddr) if err != nil { return nil, err } err = unix.Bind(s, sa) if err != nil { return nil, err } err = unix.Listen(s, unix.SOMAXCONN) if err != nil { return nil, err } f := os.NewFile(uintptr(s), "TProxy") defer f.Close() return net.FileListener(f) }
// TfoListen announces on the local network address laddr using tcp protocol and fast open option. // laddr must be in the form of "host:port". // It returns a tfo-enabled listener and an error if any. func tfoListen(laddr string) (lst net.Listener, err error) { s, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, 0) if err != nil { return } defer unix.Close(s) sa, err := tcpAddrToSockaddr(laddr) if err != nil { return } err = unix.Bind(s, sa) if err != nil { return } // set the socket to fast open mode err = unix.SetsockoptInt(s, unix.SOL_TCP, 23, TCP_FASTOPEN_VAL) if err != nil { return } err = unix.Listen(s, 10) if err != nil { return } f := os.NewFile(uintptr(s), "TFOListen") defer f.Close() return net.FileListener(f) }
func main() { fmt.Println("Listening on port :", port) counter := new(connCounter) // create socket fd, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM, 0) if err != nil { log.Fatal("socket-error: ", err) } // sa struct sa := new(unix.SockaddrInet4) sa.Port = 9090 // bind err = unix.Bind(fd, sa) if err != nil { log.Fatal("bind: ", err) } // listen err = unix.Listen(fd, 3) if err != nil { log.Fatal("listen: ", err) } for { connInfo := new(connection) // accept connection, discard SA struct newFd, _, err := unix.Accept(fd) connInfo.fd = newFd if err != nil { log.Fatal("accept: ", err) } // client reads until closes, adding // a gorutine allows dealing with more // requests. counter.mu.Lock() counter.num += 1 counter.mu.Unlock() fmt.Println("Number of connections: ", counter.num) go func(c *connection, counter *connCounter) { fmt.Printf("Conn.fd=%d\n", c.fd) for { // read c.buf = make([]byte, 50) n, err := unix.Read(c.fd, c.buf) if err != nil { log.Fatal("read: ", err) } fmt.Printf("Read: %d Value: %s\n", n, string(c.buf[0:n])) // close if string(c.buf[0:5]) == "close" { _, err = unix.Write(c.fd, []byte(`Bye bye buddy`)) if err != nil { log.Fatal("close: ", err) } err = unix.Close(c.fd) if err != nil { log.Fatal("close: ", err) } counter.mu.Lock() counter.num = counter.num - 1 counter.mu.Unlock() return } } }(connInfo, counter) } }