-
Notifications
You must be signed in to change notification settings - Fork 198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
netif: new package with netdev redesign ideas #629
base: dev
Are you sure you want to change the base?
Changes from 5 commits
731362a
60cdb7f
7e45551
570e3d2
b4f43b4
728bdbb
d4705e5
6913eaf
f657269
68ccd70
cdc76f3
1690c2c
9b74ecb
85a28fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
package nets | ||
|
||
import ( | ||
"errors" | ||
"net/netip" | ||
"time" | ||
) | ||
|
||
//go:linkname UseStack net.useNetdev | ||
func UseStack(stack Stack) | ||
|
||
// GethostByName() errors | ||
var ( | ||
ErrHostUnknown = errors.New("host unknown") | ||
ErrMalAddr = errors.New("malformed address") | ||
) | ||
|
||
// Socket errors | ||
var ( | ||
ErrFamilyNotSupported = errors.New("address family not supported") | ||
ErrProtocolNotSupported = errors.New("socket protocol/type not supported") | ||
ErrStartingDHCPClient = errors.New("error starting DHPC client") | ||
ErrNoMoreSockets = errors.New("no more sockets") | ||
ErrClosingSocket = errors.New("error closing socket") | ||
) | ||
|
||
var ( | ||
ErrConnected = errors.New("already connected") | ||
ErrConnectFailed = errors.New("connect failed") | ||
ErrConnectTimeout = errors.New("connect timed out") | ||
ErrMissingSSID = errors.New("missing WiFi SSID") | ||
ErrAuthFailure = errors.New("wifi authentication failure") | ||
ErrAuthTypeNoGood = errors.New("wifi authorization type not supported") | ||
ErrConnectModeNoGood = errors.New("connect mode not supported") | ||
ErrNotSupported = errors.New("not supported") | ||
) | ||
|
||
const ( | ||
AF_INET = 0x2 | ||
SOCK_STREAM = 0x1 | ||
SOCK_DGRAM = 0x2 | ||
SOL_SOCKET = 0x1 | ||
SO_KEEPALIVE = 0x9 | ||
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 | ||
) | ||
|
||
// Link is the minimum interface that need be implemented by any network | ||
// device driver. | ||
type Link interface { | ||
// HardwareAddr6 returns the device's 6-byte [MAC address], a.k.a EUI-48. | ||
// | ||
// [MAC address]: https://en.wikipedia.org/wiki/MAC_address | ||
HardwareAddr6() ([6]byte, error) | ||
// LinkStatus returns the state of the connection. | ||
LinkStatus() LinkStatus | ||
// MTU returns the maximum transmission unit size. | ||
MTU() int | ||
} | ||
|
||
type EthPollerLink interface { | ||
Link | ||
// SendEth sends an Ethernet packet | ||
SendEth(pkt []byte) error | ||
// RecvEthHandle sets recieve Ethernet packet callback function | ||
RecvEthHandle(func(pkt []byte) error) | ||
// PollOne tries to receive one Ethernet packet and returns true if one was | ||
PollOne() (bool, error) | ||
} | ||
|
||
type LinkWifi interface { | ||
Link | ||
// Connect device to network | ||
NetConnect(params WifiParams) error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These weren't intended to be Wifi only. I need them for this ch9120 eth driver also. SSID/Passphrase are specific to Wifi, but connect time-out, retries, watchdog timeout, dhcp mode (static or dynamic), and maybe more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From what I recall programming the ENC28J60, the connection for RJ45 connections is passive, is it not? |
||
// Disconnect device from network | ||
NetDisconnect() | ||
// Notify to register callback for network events | ||
NetNotify(cb func(Event)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NetNotify isn't wifi specific. It's for wired/wireless interfaces to indicate interface UP/DOWN. |
||
} | ||
|
||
type Stack 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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should move to Interface, correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IP Addresses are not actually Interface specific- it's network-stack level. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I think I'd leave it with no error returned since there is really no information that can be returned inside the error other than the IP address has not been set- and that piece of information can already be returned in-band inside |
||
|
||
// Berkely Sockets-like interface, Go-ified. See man page for socket(2), etc. | ||
Socket(domain int, stype int, protocol int) (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, ip netip.AddrPort) (int, error) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, just so we don't regress, this is now: Accept(sockfd int) (int, netip.AddrPort, error) |
||
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(sockfd int, level int, opt int, value interface{}) error | ||
} | ||
|
||
// Netdev is returned by `Probe` function. | ||
type Netdev interface { | ||
LinkWifi | ||
Stack | ||
} | ||
|
||
type WifiParams struct { | ||
// Connect mode | ||
ConnectMode ConnectMode | ||
|
||
// SSID of Wifi AP | ||
SSID string | ||
|
||
// Passphrase of Wifi AP | ||
Passphrase string | ||
|
||
// Wifi authorization type | ||
Auth AuthType | ||
|
||
// Wifi country code as two-char string. E.g. "XX" for world-wide, | ||
// "US" for USA, etc. | ||
CountryCode string | ||
} | ||
|
||
type Event int | ||
|
||
// Network events | ||
const ( | ||
// The device's network connection is now UP | ||
EventNetUp Event = iota | ||
// The device's network connection is now DOWN | ||
EventNetDown | ||
) | ||
|
||
type ConnectMode int | ||
|
||
// Connect modes | ||
const ( | ||
ConnectModeSTA = iota // Connect as Wifi station (default) | ||
ConnectModeAP // Connect as Wifi Access Point | ||
) | ||
|
||
type AuthType int | ||
|
||
// Wifi authorization types. Used when setting up an access point, or | ||
// connecting to an access point | ||
const ( | ||
AuthTypeWPA2 = iota // WPA2 authorization (default) | ||
AuthTypeOpen // No authorization required (open) | ||
AuthTypeWPA // WPA authorization | ||
AuthTypeWPA2Mixed // WPA2/WPA mixed authorization | ||
) | ||
|
||
type LinkStatus uint8 | ||
|
||
const ( | ||
LinkDown LinkStatus = iota | ||
LinkConnecting | ||
LinkUp | ||
) | ||
|
||
type WifiAutoconnectParams struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These aren't wifi-specific. Need same for wired. |
||
WifiParams | ||
|
||
// Retries is how many attempts to connect before returning with a | ||
// "Connect failed" error. Zero means infinite retries. | ||
Retries int // Probably should be implemented as a function | ||
|
||
// Timeout duration for each connection attempt. The default zero | ||
// value means 10sec. | ||
ConnectTimeout time.Duration | ||
|
||
// Watchdog ticker duration. On tick, the watchdog will check for | ||
// downed connection or hardware fault and try to recover the | ||
// connection. Set to zero to disable watchodog. | ||
WatchdogTimeout time.Duration | ||
} | ||
|
||
func StartWifiAutoconnect(dev Netdev, cfg WifiAutoconnectParams) error { | ||
if dev == nil { | ||
return ErrConnectModeNoGood | ||
} | ||
go func() { | ||
// Wifi autoconnect algorithm in one place, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ya, that seems good. But for wired also. |
||
// no need to implement for every single netdever. | ||
RECONNECT: | ||
for i := 0; i < cfg.Retries; i++ { | ||
err := dev.NetConnect(cfg.WifiParams) | ||
if err != nil { | ||
time.Sleep(cfg.ConnectTimeout) | ||
goto RECONNECT | ||
} | ||
for cfg.WatchdogTimeout != 0 { | ||
time.Sleep(cfg.WatchdogTimeout) | ||
if dev.LinkStatus() == LinkDown { | ||
i = 0 | ||
goto RECONNECT | ||
} | ||
} | ||
} | ||
}() | ||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
net.HardwareAddr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd avoid net.HardwareAddr for the same reasons we switched to netip.Addr, it'd be a pain to have to start checking probe implementations for the implementation details of the HardwareAddr method and if the memory was copied or a reference was passed. Also there's the issue of heap memory usage. All in all, if we can avoid net.HardwareAddr I'd do so.