Created
May 14, 2016 00:25
-
-
Save tehnerd/3fad1b3749f4eda5d317afade018427a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func CustomDial(network, addr string) (net.Conn, error) { | |
if network != "tcp" { | |
fmt.Println("network is ", network) | |
panic("CustomDial can work only with tcp") | |
} | |
sd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, 0) | |
if err != nil { | |
return nil, fmt.Errorf("cant create socket: %#v\n", err) | |
} | |
/* window clamp */ | |
err = syscall.SetsockoptInt(sd, syscall.IPPROTO_TCP, | |
TCP_WINDOW_CLAMP, BUFF_4K) | |
if err != nil { | |
return nil, fmt.Errorf("cant set window clamp: %#v\n", err) | |
} | |
/* rcv buff */ | |
err = syscall.SetsockoptInt(sd, syscall.SOL_SOCKET, | |
syscall.SO_RCVBUF, BUFF_8K) | |
if err != nil { | |
return nil, fmt.Errorf("cant set rcvbuff: %#v\n", err) | |
} | |
/* mss */ | |
err = syscall.SetsockoptInt(sd, syscall.IPPROTO_TCP, | |
syscall.TCP_MAXSEG, 1450) | |
if err != nil { | |
return nil, fmt.Errorf("cant set mss: %#v\n", err) | |
} | |
addrFields := strings.Split(addr, ":") | |
if len(addrFields) != 2 { | |
return nil, fmt.Errorf("addr doesnt contain port field") | |
} | |
port, err := strconv.Atoi(addrFields[1]) | |
if err != nil { | |
return nil, fmt.Errorf("cant convert port to int: %#v\n", err) | |
} | |
ipaddr, err := net.ResolveIPAddr("ip", addrFields[0]) | |
if err != nil { | |
return nil, fmt.Errorf("cant resolve ip addr: %#v\n", err) | |
} | |
if len(ipaddr.IP) == V4_ADDR_LEN { | |
var ipv4addr [V4_ADDR_LEN]byte | |
for cntr := 0; cntr < V4_ADDR_LEN; cntr++ { | |
ipv4addr[cntr] = ipaddr.IP[cntr] | |
} | |
sa := syscall.SockaddrInet4{ | |
Addr: ipv4addr, | |
Port: port, | |
} | |
err := syscall.Connect(sd, &sa) | |
if err != nil { | |
return nil, fmt.Errorf("cant connect to remote addr: %#v\n", err) | |
} | |
} else if len(ipaddr.IP) == V6_ADDR_LEN { | |
var ipv6addr [V6_ADDR_LEN]byte | |
for cntr := 0; cntr < V6_ADDR_LEN; cntr++ { | |
ipv6addr[cntr] = ipaddr.IP[cntr] | |
} | |
sa := syscall.SockaddrInet6{ | |
Addr: ipv6addr, | |
Port: port, | |
} | |
err := syscall.Connect(sd, &sa) | |
if err != nil { | |
return nil, fmt.Errorf("cant connect to remote addr: %#v\n", err) | |
} | |
} | |
f := os.NewFile(uintptr(sd), "") | |
c, err := net.FileConn(f) | |
f.Close() | |
return c, err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment