Beispiel #1
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)
}
Beispiel #2
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)
}
Beispiel #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)
}
Beispiel #4
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")
	}
}
Beispiel #5
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
}
Beispiel #6
0
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
}
Beispiel #7
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
}
Beispiel #8
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)
	}
}
Beispiel #9
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
}