Example #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
}
Example #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)
}