From 7890df458a2c3f23d0012738d1ea44b40b93cd14 Mon Sep 17 00:00:00 2001 From: Kasper Lund Date: Wed, 9 Oct 2024 10:56:33 +0200 Subject: [PATCH] Fix NetworkService.SELECTOR assert (#2576) --- lib/net/net.toit | 9 +-- lib/system/api/cellular.toit | 5 +- lib/system/api/ethernet.toit | 5 +- lib/system/api/network.toit | 60 +----------------- lib/system/api/wifi.toit | 5 +- lib/system/base/network.toit | 115 +++++++++++++++++++++++++++-------- 6 files changed, 105 insertions(+), 94 deletions(-) diff --git a/lib/net/net.toit b/lib/net/net.toit index c00cc7135..10c3442b8 100644 --- a/lib/net/net.toit +++ b/lib/net/net.toit @@ -14,6 +14,7 @@ import .modules.tcp as tcp-module import .modules.udp as udp-module import system.api.network show NetworkService NetworkServiceClient +import system.base.network show NetworkServiceClientBase import system.base.network show NetworkResourceProxy export IpAddress SocketAddress @@ -24,7 +25,7 @@ service_/NetworkServiceClient? ::= (NetworkServiceClient).open /// Gets the default network interface. open -> Client --name/string?=null - --service/NetworkServiceClient?=service_: + --service/NetworkServiceClientBase?=service_: if not service: throw "Network unavailable" return Client service --name=name service.connect @@ -54,13 +55,13 @@ class Client extends NetworkResourceProxy implements Interface: // client about the bits on connect. proxy-mask/int - constructor service/NetworkServiceClient --name/string? connection/List: + constructor service/NetworkServiceClientBase --name/string? connection/List: handle := connection[0] proxy-mask = connection[1] this.name = name or connection[2] super service handle - constructor service/NetworkServiceClient + constructor service/NetworkServiceClientBase --handle/int --.proxy-mask --.name: @@ -89,7 +90,7 @@ class Client extends NetworkResourceProxy implements Interface: quarantine -> none: if (proxy-mask & NetworkService.PROXY-QUARANTINE) == 0: return - (client_ as NetworkServiceClient).quarantine name + (client_ as NetworkServiceClientBase).quarantine name udp-open --port/int?=null -> udp.Socket: if is-closed: throw "Network closed" diff --git a/lib/system/api/cellular.toit b/lib/system/api/cellular.toit index 439934b77..e9aaafebf 100644 --- a/lib/system/api/cellular.toit +++ b/lib/system/api/cellular.toit @@ -2,7 +2,8 @@ // Use of this source code is governed by an MIT-style license that can be // found in the lib/LICENSE file. -import system.api.network show NetworkService NetworkServiceClient +import system.api.network show NetworkService +import system.base.network show NetworkServiceClientBase import system.services show ServiceSelector interface CellularService extends NetworkService: @@ -14,7 +15,7 @@ interface CellularService extends NetworkService: connect config/Map? -> List static CONNECT-INDEX /int ::= 1000 -class CellularServiceClient extends NetworkServiceClient implements CellularService: +class CellularServiceClient extends NetworkServiceClientBase implements CellularService: static SELECTOR ::= CellularService.SELECTOR constructor selector/ServiceSelector=SELECTOR: assert: selector.matches SELECTOR diff --git a/lib/system/api/ethernet.toit b/lib/system/api/ethernet.toit index 3d41418e3..26e8f44bc 100644 --- a/lib/system/api/ethernet.toit +++ b/lib/system/api/ethernet.toit @@ -2,7 +2,8 @@ // Use of this source code is governed by an MIT-style license that can be // found in the lib/LICENSE file. -import system.api.network show NetworkService NetworkServiceClient +import system.api.network show NetworkService +import system.base.network show NetworkServiceClientBase import system.services show ServiceSelector interface EthernetService extends NetworkService: @@ -11,7 +12,7 @@ interface EthernetService extends NetworkService: --major=0 --minor=1 -class EthernetServiceClient extends NetworkServiceClient implements EthernetService: +class EthernetServiceClient extends NetworkServiceClientBase implements EthernetService: static SELECTOR ::= EthernetService.SELECTOR constructor selector/ServiceSelector=SELECTOR: assert: selector.matches SELECTOR diff --git a/lib/system/api/network.toit b/lib/system/api/network.toit index c5d8e9459..1151567bd 100644 --- a/lib/system/api/network.toit +++ b/lib/system/api/network.toit @@ -7,6 +7,7 @@ import net.udp import net.tcp import system.services show ServiceSelector ServiceClient +import system.base.network show NetworkServiceClientBase // For references in documentation comments. import system.services show ServiceResource ServiceResourceProxy @@ -110,65 +111,8 @@ interface NetworkService: socket-mtu handle/int -> int static SOCKET-MTU-INDEX /int ::= 306 -class NetworkServiceClient extends ServiceClient implements NetworkService: +class NetworkServiceClient extends NetworkServiceClientBase: static SELECTOR ::= NetworkService.SELECTOR constructor selector/ServiceSelector=SELECTOR: assert: selector.matches SELECTOR super selector - - connect -> List: - return invoke_ NetworkService.CONNECT-INDEX null - - address handle/int -> ByteArray: - return invoke_ NetworkService.ADDRESS-INDEX handle - - resolve handle/int host/string -> List: - return invoke_ NetworkService.RESOLVE-INDEX [handle, host] - - quarantine name/string -> none: - invoke_ NetworkService.QUARANTINE-INDEX name - - udp-open handle/int port/int? -> int: - return invoke_ NetworkService.UDP-OPEN-INDEX [handle, port] - - udp-connect handle/int ip/ByteArray port/int -> none: - invoke_ NetworkService.UDP-CONNECT-INDEX [handle, ip, port] - - udp-receive handle/int -> List: - return invoke_ NetworkService.UDP-RECEIVE-INDEX handle - - udp-send handle/int data/ByteArray ip/ByteArray port/int -> none: - invoke_ NetworkService.UDP-SEND-INDEX [handle, data, ip, port] - - tcp-connect handle/int ip/ByteArray port/int -> int: - return invoke_ NetworkService.TCP-CONNECT-INDEX [handle, ip, port] - - tcp-listen handle/int port/int -> int: - return invoke_ NetworkService.TCP-LISTEN-INDEX [handle, port] - - tcp-accept handle/int -> int: - return invoke_ NetworkService.TCP-ACCEPT-INDEX handle - - tcp-close-write handle/int -> none: - invoke_ NetworkService.TCP-CLOSE-WRITE-INDEX handle - - socket-get-option handle/int option/int -> any: - return invoke_ NetworkService.SOCKET-GET-OPTION-INDEX [handle, option] - - socket-set-option handle/int option/int value/any -> none: - invoke_ NetworkService.SOCKET-SET-OPTION-INDEX [handle, option, value] - - socket-local-address handle/int -> List: - return invoke_ NetworkService.SOCKET-LOCAL-ADDRESS-INDEX handle - - socket-peer-address handle/int -> List: - return invoke_ NetworkService.SOCKET-PEER-ADDRESS-INDEX handle - - socket-read handle/int -> ByteArray?: - return invoke_ NetworkService.SOCKET-READ-INDEX handle - - socket-write handle/int data: - return invoke_ NetworkService.SOCKET-WRITE-INDEX [handle, data] - - socket-mtu handle/int -> int: - return invoke_ NetworkService.SOCKET-MTU-INDEX handle diff --git a/lib/system/api/wifi.toit b/lib/system/api/wifi.toit index 91f40abe0..c813eaf65 100644 --- a/lib/system/api/wifi.toit +++ b/lib/system/api/wifi.toit @@ -2,7 +2,8 @@ // Use of this source code is governed by an MIT-style license that can be // found in the lib/LICENSE file. -import system.api.network show NetworkService NetworkServiceClient +import system.api.network show NetworkService +import system.base.network show NetworkServiceClientBase import system.services show ServiceSelector interface WifiService extends NetworkService: @@ -26,7 +27,7 @@ interface WifiService extends NetworkService: configure config/Map? -> none static CONFIGURE-INDEX /int ::= 1004 -class WifiServiceClient extends NetworkServiceClient implements WifiService: +class WifiServiceClient extends NetworkServiceClientBase implements WifiService: static SELECTOR ::= WifiService.SELECTOR constructor selector/ServiceSelector=SELECTOR: assert: selector.matches SELECTOR diff --git a/lib/system/base/network.toit b/lib/system/base/network.toit index c303a8528..de37bc155 100644 --- a/lib/system/base/network.toit +++ b/lib/system/base/network.toit @@ -10,7 +10,6 @@ import net.tcp import system.api.network show NetworkService - NetworkServiceClient import system.services show @@ -19,33 +18,97 @@ import system.services ServiceProvider ServiceResource ServiceResourceProxy + ServiceSelector + +abstract class NetworkServiceClientBase extends ServiceClient implements NetworkService: + constructor selector/ServiceSelector: + // Extended network APIs use their own specialized selectors, so $selector + // may not match $NetworkService.SELECTOR here. + super selector + + connect -> List: + return invoke_ NetworkService.CONNECT-INDEX null + + address handle/int -> ByteArray: + return invoke_ NetworkService.ADDRESS-INDEX handle + + resolve handle/int host/string -> List: + return invoke_ NetworkService.RESOLVE-INDEX [handle, host] + + quarantine name/string -> none: + invoke_ NetworkService.QUARANTINE-INDEX name + + udp-open handle/int port/int? -> int: + return invoke_ NetworkService.UDP-OPEN-INDEX [handle, port] + + udp-connect handle/int ip/ByteArray port/int -> none: + invoke_ NetworkService.UDP-CONNECT-INDEX [handle, ip, port] + + udp-receive handle/int -> List: + return invoke_ NetworkService.UDP-RECEIVE-INDEX handle + + udp-send handle/int data/ByteArray ip/ByteArray port/int -> none: + invoke_ NetworkService.UDP-SEND-INDEX [handle, data, ip, port] + + tcp-connect handle/int ip/ByteArray port/int -> int: + return invoke_ NetworkService.TCP-CONNECT-INDEX [handle, ip, port] + + tcp-listen handle/int port/int -> int: + return invoke_ NetworkService.TCP-LISTEN-INDEX [handle, port] + + tcp-accept handle/int -> int: + return invoke_ NetworkService.TCP-ACCEPT-INDEX handle + + tcp-close-write handle/int -> none: + invoke_ NetworkService.TCP-CLOSE-WRITE-INDEX handle + + socket-get-option handle/int option/int -> any: + return invoke_ NetworkService.SOCKET-GET-OPTION-INDEX [handle, option] + + socket-set-option handle/int option/int value/any -> none: + invoke_ NetworkService.SOCKET-SET-OPTION-INDEX [handle, option, value] + + socket-local-address handle/int -> List: + return invoke_ NetworkService.SOCKET-LOCAL-ADDRESS-INDEX handle + + socket-peer-address handle/int -> List: + return invoke_ NetworkService.SOCKET-PEER-ADDRESS-INDEX handle + + socket-read handle/int -> ByteArray?: + return invoke_ NetworkService.SOCKET-READ-INDEX handle + + socket-write handle/int data: + return invoke_ NetworkService.SOCKET-WRITE-INDEX [handle, data] + + socket-mtu handle/int -> int: + return invoke_ NetworkService.SOCKET-MTU-INDEX handle class NetworkResourceProxy extends ServiceResourceProxy: on-closed_/Lambda? := null - constructor client/NetworkServiceClient handle/int: + constructor client/NetworkServiceClientBase handle/int: super client handle address -> net.IpAddress: return net.IpAddress - (client_ as NetworkServiceClient).address handle_ + (client_ as NetworkServiceClientBase).address handle_ resolve host/string -> List: - results := (client_ as NetworkServiceClient).resolve handle_ host + results := (client_ as NetworkServiceClientBase).resolve handle_ host return results.map: net.IpAddress it udp-open --port/int?=null -> udp.Socket: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase socket ::= client.udp-open handle_ port return UdpSocketResourceProxy_ client socket tcp-connect address/net.SocketAddress -> tcp.Socket: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase socket ::= client.tcp-connect handle_ address.ip.to-byte-array address.port return TcpSocketResourceProxy_ client socket tcp-listen port/int -> tcp.ServerSocket: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase socket ::= client.tcp-listen handle_ port return TcpServerSocketResourceProxy_ client socket @@ -345,32 +408,32 @@ convert-to-socket-address_ address/List offset/int=0 -> net.SocketAddress: class SocketResourceProxy_ extends ServiceResourceProxy with io.CloseableInMixin io.CloseableOutMixin: static WRITE-DATA-SIZE-MAX_ /int ::= 2048 - constructor client/NetworkServiceClient handle/int: + constructor client/NetworkServiceClientBase handle/int: super client handle local-address -> net.SocketAddress: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase return convert-to-socket-address_ (client.socket-local-address handle_) peer-address -> net.SocketAddress: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase return convert-to-socket-address_ (client.socket-peer-address handle_) read -> ByteArray?: return read_ read_ -> ByteArray?: - return (client_ as NetworkServiceClient).socket-read handle_ + return (client_ as NetworkServiceClientBase).socket-read handle_ write data/io.Data from/int=0 to/int=data.byte-size -> int: return try-write_ data from to try-write_ data/io.Data from/int to/int -> int: to = min to (from + WRITE-DATA-SIZE-MAX_) - return (client_ as NetworkServiceClient).socket-write handle_ (data.byte-slice from to) + return (client_ as NetworkServiceClientBase).socket-write handle_ (data.byte-slice from to) mtu -> int: - return (client_ as NetworkServiceClient).socket-mtu handle_ + return (client_ as NetworkServiceClientBase).socket-mtu handle_ /** Closes the proxied socket for write. The socket will still be able to read incoming data. @@ -380,58 +443,58 @@ class SocketResourceProxy_ extends ServiceResourceProxy with io.CloseableInMixin out.close close-writer_ -> none: - (client_ as NetworkServiceClient).tcp-close-write handle_ + (client_ as NetworkServiceClientBase).tcp-close-write handle_ close-reader_: // TODO(florian): Implement this. class UdpSocketResourceProxy_ extends SocketResourceProxy_ implements udp.Socket: - constructor client/NetworkServiceClient handle/int: + constructor client/NetworkServiceClientBase handle/int: super client handle receive -> udp.Datagram: - result ::= (client_ as NetworkServiceClient).udp-receive handle_ + result ::= (client_ as NetworkServiceClientBase).udp-receive handle_ return udp.Datagram result[0] (convert-to-socket-address_ result 1) send datagram/udp.Datagram -> none: address ::= datagram.address - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase client.udp-send handle_ datagram.data address.ip.to-byte-array address.port connect address/net.SocketAddress -> none: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase client.udp-connect handle_ address.ip.to-byte-array address.port broadcast -> bool: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase return client.socket-get-option handle_ NetworkService.SOCKET-OPTION-UDP-BROADCAST broadcast= value/bool: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase client.socket-set-option handle_ NetworkService.SOCKET-OPTION-UDP-BROADCAST value class TcpSocketResourceProxy_ extends SocketResourceProxy_ implements tcp.Socket: - constructor client/NetworkServiceClient handle/int: + constructor client/NetworkServiceClientBase handle/int: super client handle no-delay -> bool: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase return client.socket-get-option handle_ NetworkService.SOCKET-OPTION-TCP-NO-DELAY no-delay= value/bool -> none: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase client.socket-set-option handle_ NetworkService.SOCKET-OPTION-TCP-NO-DELAY value class TcpServerSocketResourceProxy_ extends ServiceResourceProxy implements tcp.ServerSocket: - constructor client/NetworkServiceClient handle/int: + constructor client/NetworkServiceClientBase handle/int: super client handle local-address -> net.SocketAddress: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase return convert-to-socket-address_ (client.socket-local-address handle_) accept -> tcp.Socket?: - client ::= client_ as NetworkServiceClient + client ::= client_ as NetworkServiceClientBase socket ::= client.tcp-accept handle_ return TcpSocketResourceProxy_ client socket