From 8642886f73f4f85000773c2eafc02274d5bf2163 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Mon, 18 Dec 2023 00:41:14 -0800 Subject: [PATCH] correct netdever Accept() prototype According to man page accept(2), accept returns new client sockfd and remote peer ip:port. This patch corrects the Accept() prototype in the netdever interface to not take in an ip:port arg, but rather return an ip:port for remote peer. Tested with examples/net/tcpecho on wioterminal and nano-rp2040. Here's a run with wioterminal: SERVER ============ sfeldma@nuc:~/work/drivers$ tinygo flash -monitor -target wioterminal -size short -stack-size=8kb ./examples/net/tcpecho code data bss | flash ram 110876 2552 11212 | 113428 13764 Connected to /dev/ttyACM2. Press Ctrl-C to exit. Realtek rtl8720dn Wifi network device driver (rtl8720dn) Driver version : 0.0.1 RTL8720 firmware version : 2.1.2 MAC address : 2c:f7:f1:1c:9b:2f Connecting to Wifi SSID 'test'...CONNECTED DHCP-assigned IP : 10.0.0.140 DHCP-assigned subnet : 255.255.255.0 DHCP-assigned gateway : 10.0.0.1 Starting TCP server listening on :8080 Client 10.0.0.190:50000 connected Client 10.0.0.190:50000 closed CLIENT ============= nc -p 50000 10.0.0.140 8080 --- espat/espat.go | 4 ++-- examples/net/tcpecho/main.go | 5 ++++- netdev/netdev.go | 2 +- rtl8720dn/rtl8720dn.go | 26 ++++++++++++++++++++------ wifinina/wifinina.go | 31 +++++++++++++++++++++++++------ 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/espat/espat.go b/espat/espat.go index 4ff1235..eed674c 100644 --- a/espat/espat.go +++ b/espat/espat.go @@ -218,8 +218,8 @@ func (d *Device) Listen(sockfd int, backlog int) error { return nil } -func (d *Device) Accept(sockfd int, ip netip.AddrPort) (int, error) { - return -1, netdev.ErrNotSupported +func (d *Device) Accept(sockfd int) (int, netip.AddrPort, error) { + return -1, netip.AddrPort{}, netdev.ErrNotSupported } func (d *Device) sendChunk(sockfd int, buf []byte, deadline time.Time) (int, error) { diff --git a/examples/net/tcpecho/main.go b/examples/net/tcpecho/main.go index 0356617..27faf8f 100644 --- a/examples/net/tcpecho/main.go +++ b/examples/net/tcpecho/main.go @@ -30,16 +30,18 @@ var ( var buf [1024]byte func echo(conn net.Conn) { + println("Client", conn.RemoteAddr(), "connected") defer conn.Close() _, err := io.CopyBuffer(conn, conn, buf[:]) if err != nil && err != io.EOF { log.Fatal(err.Error()) } + println("Client", conn.RemoteAddr(), "closed") } func main() { - time.Sleep(time.Second) + time.Sleep(2 * time.Second) link, _ := probe.Probe() @@ -51,6 +53,7 @@ func main() { log.Fatal(err) } + println("Starting TCP server listening on", port) l, err := net.Listen("tcp", port) if err != nil { log.Fatal(err.Error()) diff --git a/netdev/netdev.go b/netdev/netdev.go index 1709270..229b50a 100644 --- a/netdev/netdev.go +++ b/netdev/netdev.go @@ -82,7 +82,7 @@ type Netdever interface { 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) + 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 diff --git a/rtl8720dn/rtl8720dn.go b/rtl8720dn/rtl8720dn.go index 75cd8c8..701a5cd 100644 --- a/rtl8720dn/rtl8720dn.go +++ b/rtl8720dn/rtl8720dn.go @@ -437,6 +437,12 @@ func ipToName(ip netip.AddrPort) []byte { return name } +func nameToIp(name []byte) netip.AddrPort { + port := uint16(name[2])<<8 | uint16(name[3]) + addr, _ := netip.AddrFromSlice(name[4:8]) + return netip.AddrPortFrom(addr, port) +} + func (r *rtl8720dn) Bind(sockfd int, ip netip.AddrPort) error { if debugging(debugNetdev) { @@ -534,10 +540,10 @@ func (r *rtl8720dn) Listen(sockfd int, backlog int) error { return nil } -func (r *rtl8720dn) Accept(sockfd int, ip netip.AddrPort) (int, error) { +func (r *rtl8720dn) Accept(sockfd int) (int, netip.AddrPort, error) { if debugging(debugNetdev) { - fmt.Printf("[Accept] sockfd: %d, peer: %s\r\n", sockfd, ip) + fmt.Printf("[Accept] sockfd: %d\r\n", sockfd) } r.mu.Lock() @@ -546,12 +552,12 @@ func (r *rtl8720dn) Accept(sockfd int, ip netip.AddrPort) (int, error) { var newSock int32 var lsock = sock(sockfd) var socket = r.sockets[lsock] - var name = ipToName(ip) + var name = ipToName(netip.AddrPort{}) switch socket.protocol { case netdev.IPPROTO_TCP: default: - return -1, netdev.ErrProtocolNotSupported + return -1, netip.AddrPort{}, netdev.ErrProtocolNotSupported } for { @@ -570,6 +576,14 @@ func (r *rtl8720dn) Accept(sockfd int, ip netip.AddrPort) (int, error) { continue } + // Get remote peer ip:port + namelen = uint32(len(name)) + result := r.rpc_lwip_getpeername(int32(newSock), name, &namelen) + if result == -1 { + return -1, netip.AddrPort{}, fmt.Errorf("Getpeername failed") + } + raddr := nameToIp(name) + // If we've already seen this socket, we can re-use // the socket and return it. But, only if the socket // is closed. If it's not closed, we'll just come back @@ -582,12 +596,12 @@ func (r *rtl8720dn) Accept(sockfd int, ip netip.AddrPort) (int, error) { continue } // Reuse client socket - return int(newSock), nil + return int(newSock), raddr, nil } // Create new socket for client and return fd r.sockets[sock(newSock)] = newSocket(socket.protocol) - return int(newSock), nil + return int(newSock), raddr, nil } } diff --git a/wifinina/wifinina.go b/wifinina/wifinina.go index 1f2d724..3c7af39 100644 --- a/wifinina/wifinina.go +++ b/wifinina/wifinina.go @@ -676,10 +676,10 @@ func (w *wifinina) Listen(sockfd int, backlog int) error { return nil } -func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) { +func (w *wifinina) Accept(sockfd int) (int, netip.AddrPort, error) { if debugging(debugNetdev) { - fmt.Printf("[Accept] sockfd: %d, peer: %s\r\n", sockfd, ip) + fmt.Printf("[Accept] sockfd: %d\r\n", sockfd) } w.mu.Lock() @@ -692,7 +692,7 @@ func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) { switch socket.protocol { case netdev.IPPROTO_TCP: default: - return -1, netdev.ErrProtocolNotSupported + return -1, netip.AddrPort{}, netdev.ErrProtocolNotSupported } for { @@ -704,7 +704,7 @@ func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) { // Check if we've faulted if w.fault != nil { - return -1, w.fault + return -1, netip.AddrPort{}, w.fault } // TODO: BUG: Currently, a sock that is 100% busy will always be @@ -720,6 +720,8 @@ func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) { continue } + raddr := w.getRemoteData(client) + // If we've already seen this socket, we can reuse // the socket and return it. But, only if the socket // is closed. If it's not closed, we'll just come back @@ -732,12 +734,12 @@ func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) { continue } // Reuse client socket - return int(client), nil + return int(client), raddr, nil } // Create new socket for client and return fd w.sockets[client] = newSocket(socket.protocol) - return int(client), nil + return int(client), raddr, nil } } @@ -1123,6 +1125,23 @@ func (w *wifinina) accept(s sock) sock { return newsock } +func (w *wifinina) getRemoteData(s sock) netip.AddrPort { + + if debugging(debugCmd) { + fmt.Printf(" [cmdGetRemoteData] sock: %d\r\n", s) + } + + sl := make([]string, 2) + l := w.reqRspStr1(cmdGetRemoteData, uint8(s), sl) + if l != 2 { + w.faultf("getRemoteData wanted l=2, got l=%d", l) + return netip.AddrPort{} + } + ip, _ := netip.AddrFromSlice([]byte(sl[0])[:4]) + port := binary.BigEndian.Uint16([]byte(sl[1])) + return netip.AddrPortFrom(ip, port) +} + // insertDataBuf adds data to the buffer used for sending UDP data func (w *wifinina) insertDataBuf(sock sock, buf []byte) bool {