// 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) }
//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) }
// 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 UdpTProxyConn(listenAddr string) (udp *net.UDPConn, err error) { var c net.Conn s, err := unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0) if err != nil { return nil, err } //Why close here ??? defer unix.Close(s) err = unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) if err != nil { return nil, err } err = unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_BROADCAST, 1) if err != nil { return nil, err } err = unix.SetsockoptInt(s, unix.SOL_IP, unix.IP_TRANSPARENT, 1) if err != nil { return nil, err } err = unix.SetsockoptInt(s, unix.IPPROTO_IP, unix.IP_RECVORIGDSTADDR, 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 } f := os.NewFile(uintptr(s), "TProxy") defer f.Close() c, err = net.FileConn(f) if err != nil { return nil, err } var ok bool if udp, ok = c.(*net.UDPConn); ok { return } else { c.Close() return nil, errors.New("type error") } }
func NewPacketSock(ifindex int) (*packetSock, error) { fd, err := unix.Socket(unix.AF_PACKET, unix.SOCK_DGRAM, int(swap16(unix.ETH_P_IP))) if err != nil { return nil, err } addr := unix.SockaddrLinklayer{ Ifindex: ifindex, Protocol: swap16(unix.ETH_P_IP), } if err = unix.Bind(fd, &addr); err != nil { return nil, err } return &packetSock{ fd: fd, ifindex: ifindex, }, nil }
func open(fd, id int) (*Socket, error) { // Reset the device in case previous session didn't cleanup properly. if err := ioctl(uintptr(fd), hciDownDevice, uintptr(id)); err != nil { return nil, errors.Wrap(err, "can't down device") } if err := ioctl(uintptr(fd), hciUpDevice, uintptr(id)); err != nil { return nil, errors.Wrap(err, "can't up device") } // HCI User Channel requires exclusive access to the device. // The device has to be down at the time of binding. if err := ioctl(uintptr(fd), hciDownDevice, uintptr(id)); err != nil { return nil, errors.Wrap(err, "can't down device") } // Bind the RAW socket to HCI User Channel sa := unix.SockaddrHCI{Dev: uint16(id), Channel: unix.HCI_CHANNEL_USER} if err := unix.Bind(fd, &sa); err != nil { return nil, errors.Wrap(err, "can't bind socket to hci user channel") } return &Socket{fd: fd}, nil }
// see also https://github.com/jbenet/go-reuseport/blob/master/impl_unix.go#L279 func NewSocket(addr *net.UDPAddr, recvBuf int) (net.PacketConn, error) { sockFD, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|syscall.SOCK_CLOEXEC|syscall.SOCK_NONBLOCK, 0) if err != nil { return nil, err } // unix.SO_REUSEPORT is not defined on linux 386/amd64, see // https://github.com/golang/go/issues/16075 if err := unix.SetsockoptInt(sockFD, unix.SOL_SOCKET, 0xf, 1); err != nil { return nil, err } if err := unix.SetsockoptInt(sockFD, unix.SOL_SOCKET, unix.SO_RCVBUF, recvBuf); err != nil { return nil, err } sockaddr := unix.SockaddrInet4{ Port: addr.Port, } if copied := copy(sockaddr.Addr[:], addr.IP); copied != net.IPv4len { panic("did not copy enough bytes of ip address") } if err := unix.Bind(sockFD, &sockaddr); err != nil { return nil, err } osFD := os.NewFile(uintptr(sockFD), "veneursock") // this will close the FD we passed to NewFile defer osFD.Close() // however, FilePacketConn duplicates the FD, so closing the File's FD does // not affect this object's FD ret, err := net.FilePacketConn(osFD) if err != nil { return nil, err } return ret, nil }
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) } }
// TcpDial is a special tcp connection which binds a non local address as the source. // Except then the option to bind to a specific local address which the machine doesn't posses // it is exactly like any other net.Conn connection. // It is advised to use port numbered 0 in the localAddr and leave the kernel to choose which // Local port to use in order to avoid errors and binding conflicts. func TcpDial(localAddr, remoteAddr string) (conn net.Conn, err error) { fmt.Println(localAddr) fmt.Println(remoteAddr) s, err := unix.Socket(unix.AF_INET6, unix.SOCK_STREAM, 0) //In a case there was a need for a non-blocking socket an example //s, err := unix.Socket(unix.AF_INET6, unix.SOCK_STREAM |unix.SOCK_NONBLOCK, 0) if err != nil { fmt.Println(err) return nil, err } defer unix.Close(s) err = unix.SetsockoptInt(s, unix.SOL_IP, unix.IP_TRANSPARENT, 1) if err != nil { fmt.Println(err) return nil, err } err = unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) if err != nil { fmt.Println(err) return nil, err } rhost, rport, err := net.SplitHostPort(localAddr) _ = rport if err != nil { fmt.Fprintln(os.Stderr, err) } sa, err := IPv6TcpAddrToUnixSocksAddr(rhost + ":0") if err != nil { fmt.Println(err) return nil, err } remoteSocket, err := IPv6TcpAddrToUnixSocksAddr(remoteAddr) if err != nil { fmt.Println(err) return nil, err } err = unix.Bind(s, sa) if err != nil { fmt.Println(err) return nil, err } err = unix.Connect(s, remoteSocket) if err != nil { fmt.Println(err) return nil, err } f := os.NewFile(uintptr(s), "TProxyTcpClient") client, err := net.FileConn(f) if err != nil { fmt.Println(err) return nil, err } fmt.Println(client.LocalAddr()) fmt.Println(client.RemoteAddr()) return client, err }