Source file
src/net/sock_posix.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "context"
11 "internal/poll"
12 "os"
13 "syscall"
14 )
15
16
17
18 func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (fd *netFD, err error) {
19 s, err := sysSocket(family, sotype, proto)
20 if err != nil {
21 return nil, err
22 }
23 if err = setDefaultSockopts(s, family, sotype, ipv6only); err != nil {
24 poll.CloseFunc(s)
25 return nil, err
26 }
27 fd = newFD(s, family, sotype, net)
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 if laddr != nil && raddr == nil {
52 switch sotype {
53 case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET:
54 if err := fd.listenStream(ctx, laddr, listenerBacklog(), ctrlCtxFn); err != nil {
55 fd.Close()
56 return nil, err
57 }
58 return fd, nil
59 case syscall.SOCK_DGRAM:
60 if err := fd.listenDatagram(ctx, laddr, ctrlCtxFn); err != nil {
61 fd.Close()
62 return nil, err
63 }
64 return fd, nil
65 }
66 }
67 if err := fd.dial(ctx, laddr, raddr, ctrlCtxFn); err != nil {
68 fd.Close()
69 return nil, err
70 }
71 return fd, nil
72 }
73
74 func (fd *netFD) ctrlNetwork() string {
75 switch fd.net {
76 case "unix", "unixgram", "unixpacket":
77 return fd.net
78 }
79 switch fd.net[len(fd.net)-1] {
80 case '4', '6':
81 return fd.net
82 }
83 if fd.family == syscall.AF_INET {
84 return fd.net + "4"
85 }
86 return fd.net + "6"
87 }
88
89 func (fd *netFD) dial(ctx context.Context, laddr, raddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) error {
90 var c *rawConn
91 if ctrlCtxFn != nil {
92 c = newRawConn(fd)
93 var ctrlAddr string
94 if raddr != nil {
95 ctrlAddr = raddr.String()
96 } else if laddr != nil {
97 ctrlAddr = laddr.String()
98 }
99 if err := ctrlCtxFn(ctx, fd.ctrlNetwork(), ctrlAddr, c); err != nil {
100 return err
101 }
102 }
103
104 var lsa syscall.Sockaddr
105 var err error
106 if laddr != nil {
107 if lsa, err = laddr.sockaddr(fd.family); err != nil {
108 return err
109 } else if lsa != nil {
110 if err = syscall.Bind(fd.pfd.Sysfd, lsa); err != nil {
111 return os.NewSyscallError("bind", err)
112 }
113 }
114 }
115 var rsa syscall.Sockaddr
116 var crsa syscall.Sockaddr
117 if raddr != nil {
118 if rsa, err = raddr.sockaddr(fd.family); err != nil {
119 return err
120 }
121 if crsa, err = fd.connect(ctx, lsa, rsa); err != nil {
122 return err
123 }
124 fd.isConnected = true
125 } else {
126 if err := fd.init(); err != nil {
127 return err
128 }
129 }
130
131
132
133
134
135
136 lsa, _ = syscall.Getsockname(fd.pfd.Sysfd)
137 if crsa != nil {
138 fd.setAddr(fd.addrFunc()(lsa), fd.addrFunc()(crsa))
139 } else if rsa, _ = syscall.Getpeername(fd.pfd.Sysfd); rsa != nil {
140 fd.setAddr(fd.addrFunc()(lsa), fd.addrFunc()(rsa))
141 } else {
142 fd.setAddr(fd.addrFunc()(lsa), raddr)
143 }
144 return nil
145 }
146
147 func (fd *netFD) listenStream(ctx context.Context, laddr sockaddr, backlog int, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) error {
148 var err error
149 if err = setDefaultListenerSockopts(fd.pfd.Sysfd); err != nil {
150 return err
151 }
152 var lsa syscall.Sockaddr
153 if lsa, err = laddr.sockaddr(fd.family); err != nil {
154 return err
155 }
156
157 if ctrlCtxFn != nil {
158 c := newRawConn(fd)
159 if err := ctrlCtxFn(ctx, fd.ctrlNetwork(), laddr.String(), c); err != nil {
160 return err
161 }
162 }
163
164 if err = syscall.Bind(fd.pfd.Sysfd, lsa); err != nil {
165 return os.NewSyscallError("bind", err)
166 }
167 if err = listenFunc(fd.pfd.Sysfd, backlog); err != nil {
168 return os.NewSyscallError("listen", err)
169 }
170 if err = fd.init(); err != nil {
171 return err
172 }
173 lsa, _ = syscall.Getsockname(fd.pfd.Sysfd)
174 fd.setAddr(fd.addrFunc()(lsa), nil)
175 return nil
176 }
177
178 func (fd *netFD) listenDatagram(ctx context.Context, laddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) error {
179 switch addr := laddr.(type) {
180 case *UDPAddr:
181
182
183
184
185
186
187
188 if addr.IP != nil && addr.IP.IsMulticast() {
189 if err := setDefaultMulticastSockopts(fd.pfd.Sysfd); err != nil {
190 return err
191 }
192 addr := *addr
193 switch fd.family {
194 case syscall.AF_INET:
195 addr.IP = IPv4zero
196 case syscall.AF_INET6:
197 addr.IP = IPv6unspecified
198 }
199 laddr = &addr
200 }
201 }
202 var err error
203 var lsa syscall.Sockaddr
204 if lsa, err = laddr.sockaddr(fd.family); err != nil {
205 return err
206 }
207
208 if ctrlCtxFn != nil {
209 c := newRawConn(fd)
210 if err := ctrlCtxFn(ctx, fd.ctrlNetwork(), laddr.String(), c); err != nil {
211 return err
212 }
213 }
214 if err = syscall.Bind(fd.pfd.Sysfd, lsa); err != nil {
215 return os.NewSyscallError("bind", err)
216 }
217 if err = fd.init(); err != nil {
218 return err
219 }
220 lsa, _ = syscall.Getsockname(fd.pfd.Sysfd)
221 fd.setAddr(fd.addrFunc()(lsa), nil)
222 return nil
223 }
224
View as plain text