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