-
Notifications
You must be signed in to change notification settings - Fork 9
/
netdev.go
175 lines (159 loc) · 7.23 KB
/
netdev.go
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
// L3/L4 network/transport layer
package net
import (
"errors"
"net/netip"
"time"
)
const (
_AF_INET = 0x2
_SOCK_STREAM = 0x1
_SOCK_DGRAM = 0x2
_SOL_SOCKET = 0x1
_SO_KEEPALIVE = 0x9
_SO_LINGER = 0xd
_SOL_TCP = 0x6
_TCP_KEEPINTVL = 0x5
_IPPROTO_TCP = 0x6
_IPPROTO_UDP = 0x11
// Made up, not a real IP protocol number. This is used to create a
// TLS socket on the device, assuming the device supports mbed TLS.
_IPPROTO_TLS = 0xFE
_F_SETFL = 0x4
)
// netdev is the current netdev, set by the application with useNetdev().
//
// Initialized to a NOP netdev that errors out cleanly in case netdev was not
// explicitly set with useNetdev().
var netdev netdever = &nopNetdev{}
// (useNetdev is go:linkname'd from tinygo/drivers package)
func useNetdev(dev netdever) {
netdev = dev
}
// netdever is TinyGo's OSI L3/L4 network/transport layer interface. Network
// drivers implement the netdever interface, providing a common network L3/L4
// interface to TinyGo's "net" package. net.Conn implementations (TCPConn,
// UDPConn, and TLSConn) use the netdever interface for device I/O access.
//
// A netdever is passed to the "net" package using net.useNetdev().
//
// Just like a net.Conn, multiple goroutines may invoke methods on a netdever
// simultaneously.
//
// NOTE: The netdever interface is mirrored in drivers/netdev/netdev.go.
// NOTE: If making changes to this interface, mirror the changes in
// NOTE: drivers/netdev/netdev.go, and vice-versa.
type netdever interface {
// GetHostByName returns the IP address of either a hostname or IPv4
// address in standard dot notation
GetHostByName(name string) (netip.Addr, error)
// Addr returns IP address assigned to the interface, either by
// DHCP or statically
Addr() (netip.Addr, error)
// # Socket Address family/domain argument
//
// Socket address families specifies a communication domain:
// - AF_UNIX, AF_LOCAL(synonyms): Local communication For further information, see unix(7).
// - AF_INET: IPv4 Internet protocols. For further information, see ip(7).
//
// # Socket type argument
//
// Socket types which specifies the communication semantics.
// - SOCK_STREAM: Provides sequenced, reliable, two-way, connection-based
// byte streams. An out-of-band data transmission mechanism may be supported.
// - SOCK_DGRAM: Supports datagrams (connectionless, unreliable messages of
// a fixed maximum length).
//
// The type argument serves a second purpose: in addition to specifying a
// socket type, it may include the bitwise OR of any of the following values,
// to modify the behavior of socket():
// - SOCK_NONBLOCK: Set the O_NONBLOCK file status flag on the open file description.
//
// # Socket protocol argument
//
// The protocol specifies a particular protocol to be used with the
// socket. Normally only a single protocol exists to support a
// particular socket type within a given protocol family, in which
// case protocol can be specified as 0. However, it is possible
// that many protocols may exist, in which case a particular
// protocol must be specified in this manner.
//
// # Return value
//
// On success, a file descriptor for the new socket is returned. Quoting man pages:
// "On error, -1 is returned, and errno is set to indicate the error." Since
// this is not C we may use a error type native to Go to represent the error
// ocurred which by itself not only notifies of an error but also provides
// information on the error as a human readable string when calling the Error method.
Socket(domain int, stype int, protocol int) (sockfd int, _ error)
Bind(sockfd int, ip netip.AddrPort) error
Connect(sockfd int, host string, ip netip.AddrPort) error
Listen(sockfd int, backlog int) error
Accept(sockfd int) (int, netip.AddrPort, error)
// # Flags argument on Send and Recv
//
// The flags argument is formed by ORing one or more of the following values:
// - MSG_CMSG_CLOEXEC: Set the close-on-exec flag for the file descriptor. Unix.
// - MSG_DONTWAIT: Enables nonblocking operation. If call would block then returns error.
// - MSG_ERRQUEUE: (see manpage) his flag specifies that queued errors should be received
// from the socket error queue.
// - MSG_OOB: his flag requests receipt of out-of-band data that would not be received in the normal data stream.
// - MSG_PEEK: This flag causes the receive operation to return data from
// the beginning of the receive queue without removing that data from the queue.
// - MSG_TRUNC: Ask for real length of datagram even when it was longer than passed buffer.
// - MSG_WAITALL: This flag requests that the operation block until the full request is satisfied.
Send(sockfd int, buf []byte, flags int, deadline time.Time) (int, error)
Recv(sockfd int, buf []byte, flags int, deadline time.Time) (int, error)
Close(sockfd int) error
// SetSockOpt manipulates options for the socket
// referred to by the file descriptor sockfd. Options may exist at
// multiple protocol levels; they are always present at the
// uppermost socket level.
//
// # Level argument
//
// When manipulating socket options, the level at which the option
// resides and the name of the option must be specified. To
// manipulate options at the sockets API level, level is specified
// as SOL_SOCKET. To manipulate options at any other level the
// protocol number of the appropriate protocol controlling the
// option is supplied. For example, to indicate that an option is
// to be interpreted by the TCP protocol, level should be set to the
// protocol number of TCP; see getprotoent(3).
//
// # Option argument
//
// The arguments optval and optlen are used to access option values
// for setsockopt(). For getsockopt() they identify a buffer in
// which the value for the requested option(s) are to be returned.
// In Go we provide developers with an `any` interface to be able
// to pass driver-specific configurations.
SetSockOpt(sockfd int, level int, opt int, value interface{}) error
}
var ErrNetdevNotSet = errors.New("Netdev not set")
// nopNetdev is a NOP netdev that errors out any interface calls
type nopNetdev struct {
}
func (n *nopNetdev) GetHostByName(name string) (netip.Addr, error) {
return netip.Addr{}, ErrNetdevNotSet
}
func (n *nopNetdev) Addr() (netip.Addr, error) { return netip.Addr{}, ErrNetdevNotSet }
func (n *nopNetdev) Socket(domain int, stype int, protocol int) (sockfd int, _ error) {
return -1, ErrNetdevNotSet
}
func (n *nopNetdev) Bind(sockfd int, ip netip.AddrPort) error { return ErrNetdevNotSet }
func (n *nopNetdev) Connect(sockfd int, host string, ip netip.AddrPort) error { return ErrNetdevNotSet }
func (n *nopNetdev) Listen(sockfd int, backlog int) error { return ErrNetdevNotSet }
func (n *nopNetdev) Accept(sockfd int) (int, netip.AddrPort, error) {
return -1, netip.AddrPort{}, ErrNetdevNotSet
}
func (n *nopNetdev) Send(sockfd int, buf []byte, flags int, deadline time.Time) (int, error) {
return -1, ErrNetdevNotSet
}
func (n *nopNetdev) Recv(sockfd int, buf []byte, flags int, deadline time.Time) (int, error) {
return -1, ErrNetdevNotSet
}
func (n *nopNetdev) Close(sockfd int) error { return ErrNetdevNotSet }
func (n *nopNetdev) SetSockOpt(sockfd int, level int, opt int, value interface{}) error {
return ErrNetdevNotSet
}