예제 #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
파일: afpacket.go 프로젝트: songgao/ether
func (d *afpacket) Write(from ethernet.Frame) (err error) {
	copy(d.sockaddrLL.Addr[:6], []byte(from.Destination()))
	err = unix.Sendto(d.fd, []byte(from), 0, d.sockaddrLL)
	if err != nil {
		return
	}
	return
}
예제 #3
0
func (pc *packetSock) Write(packet []byte) error {
	lladdr := unix.SockaddrLinklayer{
		Ifindex:  pc.ifindex,
		Protocol: swap16(unix.ETH_P_IP),
		Halen:    uint8(len(bcastMAC)),
	}
	copy(lladdr.Addr[:], bcastMAC)

	pkt := make([]byte, minIPHdrLen+udpHdrLen+len(packet))

	fillIPHdr(pkt[0:minIPHdrLen], udpHdrLen+uint16(len(packet)))
	fillUDPHdr(pkt[minIPHdrLen:minIPHdrLen+udpHdrLen], uint16(len(packet)))

	// payload
	copy(pkt[minIPHdrLen+udpHdrLen:len(pkt)], packet)

	return unix.Sendto(pc.fd, pkt, 0, &lladdr)
}
예제 #4
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)
}