Skip to content

Commit b564228

Browse files
authored
Merge pull request #122 from BiffoBear/fix_socket_leaks
Fix DHCP socket leak
2 parents 30aa274 + 91d1f31 commit b564228

File tree

2 files changed

+91
-110
lines changed

2 files changed

+91
-110
lines changed

adafruit_wiznet5k/adafruit_wiznet5k.py

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
_MR_RST = const(0x80) # Mode Register RST
157157
# Socket mode register
158158
_SNMR_CLOSE = const(0x00)
159-
SNMR_TCP = const(0x21)
159+
_SNMR_TCP = const(0x21)
160160
SNMR_UDP = const(0x02)
161161
_SNMR_IPRAW = const(0x03)
162162
_SNMR_MACRAW = const(0x04)
@@ -492,7 +492,7 @@ def ifconfig(
492492

493493
# *** Public Socket Methods ***
494494

495-
def socket_available(self, socket_num: int, sock_type: int = SNMR_TCP) -> int:
495+
def socket_available(self, socket_num: int, sock_type: int = _SNMR_TCP) -> int:
496496
"""
497497
Number of bytes available to be read from the socket.
498498
@@ -514,7 +514,7 @@ def socket_available(self, socket_num: int, sock_type: int = SNMR_TCP) -> int:
514514
self._sock_num_in_range(socket_num)
515515

516516
number_of_bytes = self._get_rx_rcv_size(socket_num)
517-
if self.read_snsr(socket_num) == SNMR_UDP:
517+
if self._read_snsr(socket_num) == SNMR_UDP:
518518
number_of_bytes -= 8 # Subtract UDP header from packet size.
519519
if number_of_bytes < 0:
520520
raise ValueError("Negative number of bytes found on socket.")
@@ -533,14 +533,14 @@ def socket_status(self, socket_num: int) -> int:
533533
534534
:return int: The connection status.
535535
"""
536-
return self.read_snsr(socket_num)
536+
return self._read_snsr(socket_num)
537537

538538
def socket_connect(
539539
self,
540540
socket_num: int,
541541
dest: IpAddress4Raw,
542542
port: int,
543-
conn_mode: int = SNMR_TCP,
543+
conn_mode: int = _SNMR_TCP,
544544
) -> int:
545545
"""
546546
Open and verify a connection from a socket to a destination IPv4 address
@@ -567,11 +567,11 @@ def socket_connect(
567567
# initialize a socket and set the mode
568568
self.socket_open(socket_num, conn_mode=conn_mode)
569569
# set socket destination IP and port
570-
self.write_sndipr(socket_num, dest)
571-
self.write_sndport(socket_num, port)
572-
self.write_sncr(socket_num, _CMD_SOCK_CONNECT)
570+
self._write_sndipr(socket_num, dest)
571+
self._write_sndport(socket_num, port)
572+
self._write_sncr(socket_num, _CMD_SOCK_CONNECT)
573573

574-
if conn_mode == SNMR_TCP:
574+
if conn_mode == _SNMR_TCP:
575575
# wait for tcp connection establishment
576576
while self.socket_status(socket_num) != SNSR_SOCK_ESTABLISHED:
577577
time.sleep(0.001)
@@ -638,7 +638,7 @@ def release_socket(self, socket_number):
638638
WIZNET5K._sockets_reserved[socket_number - 1] = False
639639

640640
def socket_listen(
641-
self, socket_num: int, port: int, conn_mode: int = SNMR_TCP
641+
self, socket_num: int, port: int, conn_mode: int = _SNMR_TCP
642642
) -> None:
643643
"""
644644
Listen on a socket's port.
@@ -665,15 +665,15 @@ def socket_listen(
665665
self.socket_open(socket_num, conn_mode=conn_mode)
666666
self.src_port = 0
667667
# Send listen command
668-
self.write_sncr(socket_num, _CMD_SOCK_LISTEN)
668+
self._write_sncr(socket_num, _CMD_SOCK_LISTEN)
669669
# Wait until ready
670670
status = SNSR_SOCK_CLOSED
671671
while status not in (
672672
SNSR_SOCK_LISTEN,
673673
SNSR_SOCK_ESTABLISHED,
674674
_SNSR_SOCK_UDP,
675675
):
676-
status = self.read_snsr(socket_num)
676+
status = self._read_snsr(socket_num)
677677
if status == SNSR_SOCK_CLOSED:
678678
raise RuntimeError("Listening socket closed.")
679679

@@ -703,7 +703,7 @@ def socket_accept(self, socket_num: int) -> Tuple[int, Tuple[str, int]]:
703703
)
704704
return next_socknum, (dest_ip, dest_port)
705705

706-
def socket_open(self, socket_num: int, conn_mode: int = SNMR_TCP) -> None:
706+
def socket_open(self, socket_num: int, conn_mode: int = _SNMR_TCP) -> None:
707707
"""
708708
Open an IP socket.
709709
@@ -720,7 +720,7 @@ def socket_open(self, socket_num: int, conn_mode: int = SNMR_TCP) -> None:
720720
self._sock_num_in_range(socket_num)
721721
self._check_link_status()
722722
debug_msg("*** Opening socket {}".format(socket_num), self._debug)
723-
if self.read_snsr(socket_num) not in (
723+
if self._read_snsr(socket_num) not in (
724724
SNSR_SOCK_CLOSED,
725725
SNSR_SOCK_TIME_WAIT,
726726
SNSR_SOCK_FIN_WAIT,
@@ -732,22 +732,22 @@ def socket_open(self, socket_num: int, conn_mode: int = SNMR_TCP) -> None:
732732
debug_msg("* Opening W5k Socket, protocol={}".format(conn_mode), self._debug)
733733
time.sleep(0.00025)
734734

735-
self.write_snmr(socket_num, conn_mode)
735+
self._write_snmr(socket_num, conn_mode)
736736
self.write_snir(socket_num, 0xFF)
737737

738738
if self.src_port > 0:
739739
# write to socket source port
740-
self.write_sock_port(socket_num, self.src_port)
740+
self._write_sock_port(socket_num, self.src_port)
741741
else:
742742
s_port = randint(49152, 65535)
743743
while s_port in self._src_ports_in_use:
744744
s_port = randint(49152, 65535)
745-
self.write_sock_port(socket_num, s_port)
745+
self._write_sock_port(socket_num, s_port)
746746
self._src_ports_in_use[socket_num] = s_port
747747

748748
# open socket
749-
self.write_sncr(socket_num, _CMD_SOCK_OPEN)
750-
if self.read_snsr(socket_num) not in [_SNSR_SOCK_INIT, _SNSR_SOCK_UDP]:
749+
self._write_sncr(socket_num, _CMD_SOCK_OPEN)
750+
if self._read_snsr(socket_num) not in [_SNSR_SOCK_INIT, _SNSR_SOCK_UDP]:
751751
raise RuntimeError("Could not open socket in TCP or UDP mode.")
752752

753753
def socket_close(self, socket_num: int) -> None:
@@ -760,14 +760,14 @@ def socket_close(self, socket_num: int) -> None:
760760
"""
761761
debug_msg("*** Closing socket {}".format(socket_num), self._debug)
762762
self._sock_num_in_range(socket_num)
763-
self.write_sncr(socket_num, _CMD_SOCK_CLOSE)
763+
self._write_sncr(socket_num, _CMD_SOCK_CLOSE)
764764
debug_msg(" Waiting for socket to close…", self._debug)
765765
timeout = time.monotonic() + 5.0
766-
while self.read_snsr(socket_num) != SNSR_SOCK_CLOSED:
766+
while self._read_snsr(socket_num) != SNSR_SOCK_CLOSED:
767767
if time.monotonic() > timeout:
768768
raise RuntimeError(
769769
"Wiznet5k failed to close socket, status = {}.".format(
770-
self.read_snsr(socket_num)
770+
self._read_snsr(socket_num)
771771
)
772772
)
773773
time.sleep(0.0001)
@@ -783,7 +783,7 @@ def socket_disconnect(self, socket_num: int) -> None:
783783
"""
784784
debug_msg("*** Disconnecting socket {}".format(socket_num), self._debug)
785785
self._sock_num_in_range(socket_num)
786-
self.write_sncr(socket_num, _CMD_SOCK_DISCON)
786+
self._write_sncr(socket_num, _CMD_SOCK_DISCON)
787787

788788
def socket_read(self, socket_num: int, length: int) -> Tuple[int, bytes]:
789789
"""
@@ -819,7 +819,7 @@ def socket_read(self, socket_num: int, length: int) -> Tuple[int, bytes]:
819819
# After reading the received data, update Sn_RX_RD register.
820820
pointer = (pointer + bytes_on_socket) & 0xFFFF
821821
self._write_snrx_rd(socket_num, pointer)
822-
self.write_sncr(socket_num, _CMD_SOCK_RECV)
822+
self._write_sncr(socket_num, _CMD_SOCK_RECV)
823823
else:
824824
# no data on socket
825825
if self._read_snmr(socket_num) in (
@@ -906,7 +906,7 @@ def socket_write(
906906
# update sn_tx_wr to the value + data size
907907
pointer = (pointer + bytes_to_write) & 0xFFFF
908908
self._write_sntx_wr(socket_num, pointer)
909-
self.write_sncr(socket_num, _CMD_SOCK_SEND)
909+
self._write_sncr(socket_num, _CMD_SOCK_SEND)
910910

911911
# check data was transferred correctly
912912
while not self.read_snir(socket_num) & _SNIR_SEND_OK:
@@ -1057,6 +1057,11 @@ def _check_link_status(self):
10571057
if not self.link_status:
10581058
raise ConnectionError("The Ethernet connection is down.")
10591059

1060+
@staticmethod
1061+
def _read_socket_reservations() -> list[int]:
1062+
"""Return the list of reserved sockets."""
1063+
return WIZNET5K._sockets_reserved
1064+
10601065
def _read_mr(self) -> int:
10611066
"""Read from the Mode Register (MR)."""
10621067
return int.from_bytes(self._read(_REG_MR[self._chip_type], 0x00), "big")
@@ -1175,18 +1180,22 @@ def _read_sndipr(self, sock) -> bytes:
11751180
)
11761181
return bytes(data)
11771182

1178-
def write_sndipr(self, sock: int, ip_addr: bytes) -> None:
1183+
def _write_sndipr(self, sock: int, ip_addr: bytes) -> None:
11791184
"""Write to socket destination IP Address."""
11801185
for offset, value in enumerate(ip_addr):
11811186
self._write_socket_register(
11821187
sock, _REG_SNDIPR[self._chip_type] + offset, value
11831188
)
11841189

1185-
def write_sndport(self, sock: int, port: int) -> None:
1190+
def _read_sndport(self, sock: int) -> int:
1191+
"""Read socket destination port."""
1192+
return self._read_two_byte_sock_reg(sock, _REG_SNDPORT[self._chip_type])
1193+
1194+
def _write_sndport(self, sock: int, port: int) -> None:
11861195
"""Write to socket destination port."""
11871196
self._write_two_byte_sock_reg(sock, _REG_SNDPORT[self._chip_type], port)
11881197

1189-
def read_snsr(self, sock: int) -> int:
1198+
def _read_snsr(self, sock: int) -> int:
11901199
"""Read Socket n Status Register."""
11911200
return self._read_socket_register(sock, _REG_SNSR[self._chip_type])
11921201

@@ -1202,15 +1211,15 @@ def _read_snmr(self, sock: int) -> int:
12021211
"""Read the socket MR register."""
12031212
return self._read_socket_register(sock, _REG_SNMR)
12041213

1205-
def write_snmr(self, sock: int, protocol: int) -> None:
1214+
def _write_snmr(self, sock: int, protocol: int) -> None:
12061215
"""Write to Socket n Mode Register."""
12071216
self._write_socket_register(sock, _REG_SNMR, protocol)
12081217

1209-
def write_sock_port(self, sock: int, port: int) -> None:
1218+
def _write_sock_port(self, sock: int, port: int) -> None:
12101219
"""Write to the socket port number."""
12111220
self._write_two_byte_sock_reg(sock, _REG_SNPORT[self._chip_type], port)
12121221

1213-
def write_sncr(self, sock: int, data: int) -> None:
1222+
def _write_sncr(self, sock: int, data: int) -> None:
12141223
"""Write to socket command register."""
12151224
self._write_socket_register(sock, _REG_SNCR[self._chip_type], data)
12161225
# Wait for command to complete before continuing.

0 commit comments

Comments
 (0)