Пример #1
0
//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)
}
Пример #2
0
// 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)
}
Пример #3
0
// 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)
}
Пример #4
0
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)
	}
}