-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathdial.go
More file actions
283 lines (253 loc) · 9.3 KB
/
dial.go
File metadata and controls
283 lines (253 loc) · 9.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
// TINYGO: The following is copied and modified from Go 1.26.2 official implementation.
// TINYGO: Omit DualStack support
// TINYGO: Omit Fast Fallback support
// TINYGO: Don't allow alternate resolver
// TINYGO: Omit DialTimeout
// TINYGO: Omit Multipath TCP
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package net
import (
"context"
"errors"
"fmt"
"internal/bytealg"
"syscall"
"time"
)
const (
// defaultTCPKeepAlive is a default constant value for TCPKeepAlive times
// See go.dev/issue/31510
defaultTCPKeepAlive = 15 * time.Second
)
// mptcpStatus is a tristate for Multipath TCP, see go.dev/issue/56539
type mptcpStatus uint8
// TINYGO: mptcpStatusListen stub for ListenConfig compatibility
type mptcpStatusListen uint8
// A Dialer contains options for connecting to an address.
//
// The zero value for each field is equivalent to dialing
// without that option. Dialing with the zero value of Dialer
// is therefore equivalent to just calling the [Dial] function.
//
// It is safe to call Dialer's methods concurrently.
type Dialer struct {
// Timeout is the maximum amount of time a dial will wait for
// a connect to complete. If Deadline is also set, it may fail
// earlier.
//
// The default is no timeout.
//
// When using TCP and dialing a host name with multiple IP
// addresses, the timeout may be divided between them.
//
// With or without a timeout, the operating system may impose
// its own earlier timeout. For instance, TCP timeouts are
// often around 3 minutes.
Timeout time.Duration
// Deadline is the absolute point in time after which dials
// will fail. If Timeout is set, it may fail earlier.
// Zero means no deadline, or dependent on the operating system
// as with the Timeout option.
Deadline time.Time
// LocalAddr is the local address to use when dialing an
// address. The address must be of a compatible type for the
// network being dialed.
// If nil, a local address is automatically chosen.
LocalAddr Addr
// KeepAlive specifies the interval between keep-alive
// probes for an active network connection.
//
// KeepAlive is ignored if KeepAliveConfig.Enable is true.
//
// If zero, keep-alive probes are sent with a default value
// (currently 15 seconds), if supported by the protocol and operating
// system. Network protocols or operating systems that do
// not support keep-alive ignore this field.
// If negative, keep-alive probes are disabled.
KeepAlive time.Duration
// KeepAliveConfig specifies the keep-alive probe configuration
// for an active network connection, when supported by the
// protocol and operating system.
//
// If KeepAliveConfig.Enable is true, keep-alive probes are enabled.
// If KeepAliveConfig.Enable is false and KeepAlive is negative,
// keep-alive probes are disabled.
KeepAliveConfig KeepAliveConfig
}
// Dial connects to the address on the named network.
//
// See Go "net" package Dial() for more information.
//
// Note: Tinygo Dial supports a subset of networks supported by Go Dial,
// specifically: "tcp", "tcp4", "udp", and "udp4". IP and unix networks are
// not supported.
func Dial(network, address string) (Conn, error) {
var d Dialer
return d.Dial(network, address)
}
// DialTimeout acts like [Dial] but takes a timeout.
//
// The timeout includes name resolution, if required.
// When using TCP, and the host in the address parameter resolves to
// multiple IP addresses, the timeout is spread over each consecutive
// dial, such that each is given an appropriate fraction of the time
// to connect.
//
// See func Dial for a description of the network and address
// parameters.
func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {
d := Dialer{Timeout: timeout}
return d.Dial(network, address)
}
// Dial connects to the address on the named network.
//
// See func Dial for a description of the network and address
// parameters.
//
// Dial uses [context.Background] internally; to specify the context, use
// [Dialer.DialContext].
func (d *Dialer) Dial(network, address string) (Conn, error) {
return d.DialContext(context.Background(), network, address)
}
// DialContext connects to the address on the named network using
// the provided context.
//
// The provided Context must be non-nil. If the context expires before
// the connection is complete, an error is returned. Once successfully
// connected, any expiration of the context will not affect the
// connection.
//
// When using TCP, and the host in the address parameter resolves to multiple
// network addresses, any dial timeout (from d.Timeout or ctx) is spread
// over each consecutive dial, such that each is given an appropriate
// fraction of the time to connect.
// For example, if a host has 4 IP addresses and the timeout is 1 minute,
// the connect to each single address will be given 15 seconds to complete
// before trying the next one.
//
// See func [Dial] for a description of the network and address
// parameters.
func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error) {
// TINYGO: Ignoring context
switch network {
case "tcp", "tcp4":
raddr, err := ResolveTCPAddr(network, address)
if err != nil {
return nil, err
}
return DialTCP(network, nil, raddr)
case "udp", "udp4":
raddr, err := ResolveUDPAddr(network, address)
if err != nil {
return nil, err
}
return DialUDP(network, nil, raddr)
}
return nil, fmt.Errorf("Network %s not supported", network)
}
// ListenConfig contains options for listening to an address.
type ListenConfig struct {
// If Control is not nil, it is called after creating the network
// connection but before binding it to the operating system.
//
// Network and address parameters passed to Control function are not
// necessarily the ones passed to Listen. Calling Listen with TCP networks
// will cause the Control function to be called with "tcp4" or "tcp6",
// UDP networks become "udp4" or "udp6", IP networks become "ip4" or "ip6",
// and other known networks are passed as-is.
Control func(network, address string, c syscall.RawConn) error
// KeepAlive specifies the keep-alive period for network
// connections accepted by this listener.
//
// KeepAlive is ignored if KeepAliveConfig.Enable is true.
//
// If zero, keep-alive are enabled if supported by the protocol
// and operating system. Network protocols or operating systems
// that do not support keep-alive ignore this field.
// If negative, keep-alive are disabled.
KeepAlive time.Duration
// KeepAliveConfig specifies the keep-alive probe configuration
// for an active network connection, when supported by the
// protocol and operating system.
//
// If KeepAliveConfig.Enable is true, keep-alive probes are enabled.
// If KeepAliveConfig.Enable is false and KeepAlive is negative,
// keep-alive probes are disabled.
KeepAliveConfig KeepAliveConfig
// If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
// used, any call to Listen with "tcp(4|6)" as network will use MPTCP if
// supported by the operating system.
mptcpStatus mptcpStatusListen
}
// Listen announces on the local network address.
//
// See func Listen for a description of the network and address
// parameters.
//
// The ctx argument is used while resolving the address on which to listen;
// it does not affect the returned Listener.
func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (Listener, error) {
return nil, errors.New("dial:ListenConfig:Listen not implemented")
}
// ListenPacket announces on the local network address.
//
// See func ListenPacket for a description of the network and address
// parameters.
//
// The ctx argument is used while resolving the address on which to listen;
// it does not affect the returned PacketConn.
func (lc *ListenConfig) ListenPacket(ctx context.Context, network, address string) (PacketConn, error) {
return nil, errors.New("dial:ListenConfig:ListenPacket not implemented")
}
func parseNetwork(ctx context.Context, network string, needsProto bool) (afnet string, proto int, err error) {
i := bytealg.LastIndexByteString(network, ':')
if i < 0 { // no colon
switch network {
case "tcp", "tcp4", "tcp6":
case "udp", "udp4", "udp6":
case "ip", "ip4", "ip6":
if needsProto {
return "", 0, UnknownNetworkError(network)
}
case "unix", "unixgram", "unixpacket":
default:
return "", 0, UnknownNetworkError(network)
}
return network, 0, nil
}
afnet = network[:i]
switch afnet {
case "ip", "ip4", "ip6":
protostr := network[i+1:]
proto, i, ok := dtoi(protostr)
if !ok || i != len(protostr) {
proto, err = lookupProtocol(ctx, protostr)
if err != nil {
return "", 0, err
}
}
return afnet, proto, nil
}
return "", 0, UnknownNetworkError(network)
}
// Listen announces on the local network address.
//
// See Go "net" package Listen() for more information.
//
// Note: Tinygo Listen supports a subset of networks supported by Go Listen,
// specifically: "tcp", "tcp4". "tcp6" and unix networks are not supported.
func Listen(network, address string) (Listener, error) {
// println("Listen", address)
switch network {
case "tcp", "tcp4":
default:
return nil, fmt.Errorf("Network %s not supported", network)
}
laddr, err := ResolveTCPAddr(network, address)
if err != nil {
return nil, err
}
return listenTCP(laddr)
}