Source file
src/net/iprawsock.go
1
2
3
4
5 package net
6
7 import (
8 "context"
9 "net/netip"
10 "syscall"
11 )
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 func ipAddrFromAddr(addr netip.Addr) *IPAddr {
35 return &IPAddr{
36 IP: addr.AsSlice(),
37 Zone: addr.Zone(),
38 }
39 }
40
41
42 type IPAddr struct {
43 IP IP
44 Zone string
45 }
46
47
48 func (a *IPAddr) Network() string { return "ip" }
49
50 func (a *IPAddr) String() string {
51 if a == nil {
52 return "<nil>"
53 }
54 ip := ipEmptyString(a.IP)
55 if a.Zone != "" {
56 return ip + "%" + a.Zone
57 }
58 return ip
59 }
60
61 func (a *IPAddr) isWildcard() bool {
62 if a == nil || a.IP == nil {
63 return true
64 }
65 return a.IP.IsUnspecified()
66 }
67
68 func (a *IPAddr) opAddr() Addr {
69 if a == nil {
70 return nil
71 }
72 return a
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 func ResolveIPAddr(network, address string) (*IPAddr, error) {
89 if network == "" {
90 network = "ip"
91 }
92 afnet, _, err := parseNetwork(context.Background(), network, false)
93 if err != nil {
94 return nil, err
95 }
96 switch afnet {
97 case "ip", "ip4", "ip6":
98 default:
99 return nil, UnknownNetworkError(network)
100 }
101 addrs, err := DefaultResolver.internetAddrList(context.Background(), afnet, address)
102 if err != nil {
103 return nil, err
104 }
105 return addrs.forResolve(network, address).(*IPAddr), nil
106 }
107
108
109
110 type IPConn struct {
111 conn
112 }
113
114
115
116 func (c *IPConn) SyscallConn() (syscall.RawConn, error) {
117 if !c.ok() {
118 return nil, syscall.EINVAL
119 }
120 return newRawConn(c.fd), nil
121 }
122
123
124 func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
125 if !c.ok() {
126 return 0, nil, syscall.EINVAL
127 }
128 n, addr, err := c.readFrom(b)
129 if err != nil {
130 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
131 }
132 return n, addr, err
133 }
134
135
136 func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
137 if !c.ok() {
138 return 0, nil, syscall.EINVAL
139 }
140 n, addr, err := c.readFrom(b)
141 if err != nil {
142 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
143 }
144 if addr == nil {
145 return n, nil, err
146 }
147 return n, addr, err
148 }
149
150
151
152
153
154
155
156
157 func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
158 if !c.ok() {
159 return 0, 0, 0, nil, syscall.EINVAL
160 }
161 n, oobn, flags, addr, err = c.readMsg(b, oob)
162 if err != nil {
163 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
164 }
165 return
166 }
167
168
169 func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
170 if !c.ok() {
171 return 0, syscall.EINVAL
172 }
173 n, err := c.writeTo(b, addr)
174 if err != nil {
175 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
176 }
177 return n, err
178 }
179
180
181 func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
182 if !c.ok() {
183 return 0, syscall.EINVAL
184 }
185 a, ok := addr.(*IPAddr)
186 if !ok {
187 return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
188 }
189 n, err := c.writeTo(b, a)
190 if err != nil {
191 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
192 }
193 return n, err
194 }
195
196
197
198
199
200
201
202 func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
203 if !c.ok() {
204 return 0, 0, syscall.EINVAL
205 }
206 n, oobn, err = c.writeMsg(b, oob, addr)
207 if err != nil {
208 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
209 }
210 return
211 }
212
213 func newIPConn(fd *netFD) *IPConn { return &IPConn{conn{fd}} }
214
215
216
217
218
219
220
221
222 func DialIP(network string, laddr, raddr *IPAddr) (*IPConn, error) {
223 return dialIP(context.Background(), nil, network, laddr, raddr)
224 }
225
226 func dialIP(ctx context.Context, dialer *Dialer, network string, laddr, raddr *IPAddr) (*IPConn, error) {
227 if raddr == nil {
228 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
229 }
230 sd := &sysDialer{network: network, address: raddr.String()}
231 if dialer != nil {
232 sd.Dialer = *dialer
233 }
234 c, err := sd.dialIP(ctx, laddr, raddr)
235 if err != nil {
236 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
237 }
238 return c, nil
239 }
240
241
242
243
244
245
246
247
248 func ListenIP(network string, laddr *IPAddr) (*IPConn, error) {
249 if laddr == nil {
250 laddr = &IPAddr{}
251 }
252 sl := &sysListener{network: network, address: laddr.String()}
253 c, err := sl.listenIP(context.Background(), laddr)
254 if err != nil {
255 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
256 }
257 return c, nil
258 }
259
View as plain text