Пример #1
0
// dial tcp with tcp fastopen
// 第一个包体积不要太大,需要小于一定数量,否则会被吃掉(正确性问题),
// 如果过大,此处会在连接时发送前一部分,连接后又发送一部分
func TfoDial(nextAddr string, data []byte) (conn net.Conn, err error) {
	s, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM, 0)
	if err != nil {
		return nil, err
	}
	defer unix.Close(s)
	sa, err := kmgUnix.IPv4TcpAddrToUnixSocksAddr(nextAddr)
	if err != nil {
		return nil, err
	}
	if len(data) <= tfoFirstSize {
		err = unix.Sendto(s, data, unix.MSG_FASTOPEN, sa)
		if err != nil {
			return
		}
	} else {
		err = unix.Sendto(s, data[:tfoFirstSize], unix.MSG_FASTOPEN, sa)
		if err != nil {
			return
		}
	}
	f := os.NewFile(uintptr(s), "TFODial")
	defer f.Close()
	conn, err = net.FileConn(f)
	if err != nil {
		return
	}
	if len(data) > tfoFirstSize {
		_, err = conn.Write(data[tfoFirstSize:])
		if err != nil {
			return nil, err
		}
	}
	return conn, nil
}
Пример #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
//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)
}
Пример #4
0
// NewSocket returns a HCI User Channel of specified device id.
// If id is -1, the first available HCI device is returned.
func NewSocket(id int) (*Socket, error) {
	var err error
	// Create RAW HCI Socket.
	fd, err := unix.Socket(unix.AF_BLUETOOTH, unix.SOCK_RAW, unix.BTPROTO_HCI)
	if err != nil {
		return nil, errors.Wrap(err, "can't create socket")
	}

	if id != -1 {
		return open(fd, id)
	}

	req := devListRequest{devNum: hciMaxDevices}
	if err = ioctl(uintptr(fd), hciGetDeviceList, uintptr(unsafe.Pointer(&req))); err != nil {
		return nil, errors.Wrap(err, "can't get device list")
	}
	var msg string
	for id := 0; id < int(req.devNum); id++ {
		s, err := open(fd, id)
		if err == nil {
			return s, nil
		}
		msg = msg + fmt.Sprintf("(hci%d: %s)", id, err)
	}
	return nil, errors.Errorf("no devices available: %s", msg)
}
Пример #5
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)
}
Пример #6
0
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")
	}
}
Пример #7
0
func newDev(ifce *net.Interface, frameFilter FrameFilter) (dev Dev, err error) {
	d := new(afpacket)
	d.ifce = ifce
	d.filter = frameFilter

	d.fd, err = unix.Socket(unix.AF_PACKET, unix.SOCK_RAW, htons(unix.ETH_P_ALL))
	if err != nil {
		return
	}

	d.sockaddrLL = new(unix.SockaddrLinklayer)
	d.sockaddrLL.Ifindex = ifce.Index
	d.sockaddrLL.Halen = 6

	dev = d
	return
}
Пример #8
0
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
}
Пример #9
0
// TfoDial dials to addr using tcp protocol with fast open option set,
// addr should be in the form of "addr:port",
// the data is sent along with the first syn packet of tcp handshake.
// It returns a established connection and an error if any.
func tfoDial(addr string, data []byte) (conn net.Conn, err error) {
	fd, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM, 0)
	if err != nil {
		return
	}
	defer unix.Close(fd)

	sa, err := tcpAddrToSockaddr(addr)
	if err != nil {
		return
	}

	err = unix.Sendto(fd, data, unix.MSG_FASTOPEN, sa)
	if err != nil {
		return
	}

	f := os.NewFile(uintptr(fd), "TFODial")
	defer f.Close()

	return net.FileConn(f)
}
Пример #10
0
// 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
}
Пример #11
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)
	}
}
Пример #12
0
// 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
}