Source file
src/net/rawconn_unix_test.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "errors"
11 "syscall"
12 )
13
14 func readRawConn(c syscall.RawConn, b []byte) (int, error) {
15 var operr error
16 var n int
17 err := c.Read(func(s uintptr) bool {
18 n, operr = syscall.Read(int(s), b)
19 if operr == syscall.EAGAIN {
20 return false
21 }
22 return true
23 })
24 if err != nil {
25 return n, err
26 }
27 return n, operr
28 }
29
30 func writeRawConn(c syscall.RawConn, b []byte) error {
31 var operr error
32 err := c.Write(func(s uintptr) bool {
33 _, operr = syscall.Write(int(s), b)
34 if operr == syscall.EAGAIN {
35 return false
36 }
37 return true
38 })
39 if err != nil {
40 return err
41 }
42 return operr
43 }
44
45 func controlRawConn(c syscall.RawConn, addr Addr) error {
46 var operr error
47 fn := func(s uintptr) {
48 _, operr = syscall.GetsockoptInt(int(s), syscall.SOL_SOCKET, syscall.SO_REUSEADDR)
49 if operr != nil {
50 return
51 }
52 switch addr := addr.(type) {
53 case *TCPAddr:
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 if addr.IP.To16() != nil && addr.IP.To4() == nil {
75 operr = syscall.SetsockoptInt(int(s), syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, 1)
76 } else if addr.IP.To16() == nil && addr.IP.To4() != nil {
77 operr = syscall.SetsockoptInt(int(s), syscall.IPPROTO_IP, syscall.IP_TTL, 1)
78 }
79 }
80 }
81 if err := c.Control(fn); err != nil {
82 return err
83 }
84 return operr
85 }
86
87 func controlOnConnSetup(network string, address string, c syscall.RawConn) error {
88 var operr error
89 var fn func(uintptr)
90 switch network {
91 case "tcp", "udp", "ip":
92 return errors.New("ambiguous network: " + network)
93 case "unix", "unixpacket", "unixgram":
94 fn = func(s uintptr) {
95 _, operr = syscall.GetsockoptInt(int(s), syscall.SOL_SOCKET, syscall.SO_ERROR)
96 }
97 default:
98 switch network[len(network)-1] {
99 case '4':
100 fn = func(s uintptr) {
101 operr = syscall.SetsockoptInt(int(s), syscall.IPPROTO_IP, syscall.IP_TTL, 1)
102 }
103 case '6':
104 fn = func(s uintptr) {
105 operr = syscall.SetsockoptInt(int(s), syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, 1)
106 }
107 default:
108 return errors.New("unknown network: " + network)
109 }
110 }
111 if err := c.Control(fn); err != nil {
112 return err
113 }
114 return operr
115 }
116
View as plain text