Skip to content

Commit 8820a59

Browse files
committed
Re-araranged stack subsystems
1 parent 1b21a44 commit 8820a59

21 files changed

+404
-327
lines changed

examples/run_stack.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
Ip6Host,
5151
MacAddress,
5252
)
53-
from pytcp import TcpIpStack, initialize_interface
53+
from pytcp import stack
5454

5555

5656
@click.command()
@@ -104,17 +104,14 @@ def cli(
104104
Start PyTCP stack and stop it when user presses Ctrl-C.
105105
"""
106106

107-
fd, mtu = initialize_interface(interface)
108-
109107
if ip6_host:
110108
ip6_host.gateway = ip6_gateway
111109

112110
if ip4_host:
113111
ip4_host.gateway = ip4_gateway
114112

115-
stack = TcpIpStack(
116-
fd=fd,
117-
mtu=mtu,
113+
stack.init(
114+
*stack.initialize_interface(interface),
118115
mac_address=mac_address,
119116
ip6_host=ip6_host,
120117
ip4_host=ip4_host,

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,5 @@ disable = """
8787
no-member,
8888
too-many-ancestors,
8989
redefined-outer-name,
90+
global-statement,
9091
"""

pytcp/__init__.py

Lines changed: 1 addition & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -27,142 +27,9 @@
2727

2828

2929
"""
30-
Module contains the main PyTCP stack class.
30+
Package contains the PyTCP stack modules.
3131
3232
pytcp/__init__.py
3333
3434
ver 3.0.2
3535
"""
36-
37-
38-
import fcntl
39-
import os
40-
import struct
41-
import sys
42-
43-
from net_addr.ip4_host import Ip4HostOrigin
44-
from net_addr.ip6_host import Ip6HostOrigin
45-
46-
from net_addr import Ip4Host, Ip6Host, MacAddress
47-
from pytcp import config, stack
48-
from pytcp.lib.logger import log
49-
from pytcp.socket.socket import ( # noqa: F401
50-
AddressFamily,
51-
IpProto,
52-
ReceiveTimeout,
53-
Socket,
54-
SocketType,
55-
gaierror,
56-
)
57-
58-
TUNSETIFF = 0x400454CA
59-
IFF_TUN = 0x0001
60-
IFF_TAP = 0x0002
61-
IFF_NO_PI = 0x1000
62-
63-
64-
def initialize_interface(if_name: str, /) -> tuple[int, int]:
65-
"""
66-
Initialize the TAP/TUN interface.
67-
"""
68-
69-
match if_name[0:3].lower():
70-
case "tap":
71-
if_type = IFF_TAP
72-
mtu = config.INTERFACE__TAP__MTU
73-
case "tun":
74-
if_type = IFF_TUN
75-
mtu = config.INTERFACE__TUN__MTU
76-
case _:
77-
log(
78-
"stack",
79-
"<CRIT>Interface name must start with 'tap' or 'tun'</>",
80-
)
81-
sys.exit(-1)
82-
83-
try:
84-
fd = os.open("/dev/net/tun", os.O_RDWR)
85-
86-
except FileNotFoundError:
87-
log("stack", "<CRIT>Unable to access '/dev/net/tun' device</>")
88-
sys.exit(-1)
89-
90-
fcntl.ioctl(
91-
fd,
92-
TUNSETIFF,
93-
struct.pack("16sH", if_name.encode(), if_type | IFF_NO_PI),
94-
)
95-
96-
return fd, mtu
97-
98-
99-
class TcpIpStack:
100-
"""
101-
Main PyTCP library class.
102-
"""
103-
104-
def __init__(
105-
self,
106-
fd: int,
107-
mtu: int,
108-
*,
109-
mac_address: MacAddress | None = None,
110-
ip4_host: Ip4Host | None = None,
111-
ip6_host: Ip6Host | None = None,
112-
):
113-
"""
114-
Initialize stack on the provided interface.
115-
"""
116-
117-
self._fd = fd
118-
self._mtu = mtu
119-
120-
# Set the MAC address.
121-
if mac_address is not None:
122-
stack.packet_handler._assign_mac_address(
123-
mac_unicast=MacAddress(mac_address)
124-
)
125-
126-
# Set the IPv4 address.
127-
if config.IP4__SUPPORT_ENABLED is True:
128-
if ip4_host is None:
129-
config.IP4__HOST_DHCP = True
130-
else:
131-
ip4_host.origin = Ip4HostOrigin.STATIC
132-
stack.packet_handler._assign_ip4_address(ip4_host=ip4_host)
133-
config.IP4__HOST_DHCP = False
134-
135-
# Set the IPv6 address.
136-
if config.IP6__SUPPORT_ENABLED is True:
137-
if ip6_host is None:
138-
config.IP6__LLA_AUTOCONFIG = True
139-
config.IP6__GUA_AUTOCONFIG = True
140-
else:
141-
ip6_host.origin = Ip6HostOrigin.STATIC
142-
stack.packet_handler._assign_ip6_address(ip6_host=ip6_host)
143-
config.IP6__LLA_AUTOCONFIG = True
144-
config.IP6__GUA_AUTOCONFIG = False
145-
146-
def start(self) -> None:
147-
"""
148-
Start stack components.
149-
"""
150-
151-
stack.timer.start()
152-
stack.arp_cache.start()
153-
stack.nd_cache.start()
154-
stack.rx_ring.start(fd=self._fd)
155-
stack.tx_ring.start(fd=self._fd, mtu=self._mtu)
156-
stack.packet_handler.start()
157-
158-
def stop(self) -> None:
159-
"""
160-
Stop stack components.
161-
"""
162-
163-
stack.packet_handler.stop()
164-
stack.tx_ring.stop()
165-
stack.rx_ring.stop()
166-
stack.arp_cache.stop()
167-
stack.nd_cache.stop()
168-
stack.timer.stop()

pytcp/config.py

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,6 @@
3939

4040
assert version_info >= (3, 12), "PyTCP requires Python version 3.12 or higher."
4141

42-
# TAP interface MTU, describes how much payload Ethernet packet can carry.
43-
INTERFACE__TAP__MTU = 1500
44-
45-
# TUN interface MTU..
46-
INTERFACE__TUN__MTU = 1500
47-
48-
49-
# Support for IPv6 and IPv4, at least one should be anabled.
50-
IP6__SUPPORT_ENABLED = True
51-
IP4__SUPPORT_ENABLED = True
5242

5343
# Logger configuration - LOG__CHANNEL sets which subsystems of stack log to the
5444
# console, LOG__DEBUG adds info about class/method caller.
@@ -78,16 +68,6 @@
7868
}
7969
LOG__DEBUG = False
8070

81-
# Unicast MAC addresses assigned to stack, currently there is not any kind of
82-
# duplicate MAC detection performed. This can be overridden when stack object
83-
# is created.
84-
ETHERNET__MAC_ADDRESS = "02:00:00:77:77:77"
85-
86-
# IPv6 address auto configuration is implemented using EUI64 addressing and
87-
# ICMPv6 Router Advertisement messages.
88-
IP6__LLA_AUTOCONFIG = True
89-
IP6__GUA_AUTOCONFIG = True
90-
9171
# IPv6 default Hop Limit value.
9272
IP6__DEFAULT_HOP_LIMIT = 64
9373

@@ -104,19 +84,6 @@
10484
IP4__FRAG_FLOW_TIMEOUT = 5
10585
IP6__FRAG_FLOW_TIMEOUT = 5
10686

107-
# IPv4 DHCP based address configuration.
108-
IP4__HOST_DHCP = True
109-
110-
# ARP cache configuration.
111-
ARP__CACHE__ENTRY_MAX_AGE = 3600
112-
ARP__CACHE__ENTRY_REFRESH_TIME = 300
113-
ARP__CACHE__UPDATE_FROM_DIRECT_REQUEST = True
114-
ARP__CACHE__UPDATE_FROM_GRATUITIOUS_REPLY = True
115-
116-
# ICMPv6 ND cache configuration.
117-
ICMP6__ND__CACHE__ENTRY_MAX_AGE = 3600
118-
ICMP6__ND__CACHE__ENTRY_REFRESH_TIME = 300
119-
12087
# TCP/UDP ephemeral port range to be used by outbound connections.
12188
EPHEMERAL_PORT_RANGE = range(32168, 60700, 2)
12289

pytcp/socket/tcp__session.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
from enum import auto
5050
from typing import TYPE_CHECKING, Any
5151

52-
from pytcp import config, stack
52+
from pytcp import stack
5353
from pytcp.lib.logger import log
5454
from pytcp.lib.name_enum import NameEnum
5555

@@ -68,6 +68,8 @@
6868
100 # Delay between consecutive delayed ACK outbound packets
6969
)
7070

71+
INTERFACE__TAP__MTU = 1500
72+
7173

7274
class TcpSessionError(Exception):
7375
"""
@@ -209,7 +211,7 @@ def __init__(
209211
self._rcv_una: int = 0
210212

211213
# Maximum segment size
212-
self._rcv_mss: int = config.INTERFACE__TAP__MTU - 40
214+
self._rcv_mss: int = INTERFACE__TAP__MTU - 40
213215

214216
# Window size
215217
self._rcv_wnd: int = 65535
@@ -883,7 +885,7 @@ def _tcp_fsm_listen(
883885
)
884886
# Initialize session parameters
885887
self._snd_mss = min(
886-
packet_rx_md.tcp__mss, config.INTERFACE__TAP__MTU - 40
888+
packet_rx_md.tcp__mss, INTERFACE__TAP__MTU - 40
887889
)
888890
self._snd_wnd = (
889891
packet_rx_md.tcp__win << self._snd_wsc
@@ -940,7 +942,7 @@ def _tcp_fsm_syn_sent(
940942
):
941943
# Initialize session parameters
942944
self._snd_mss = min(
943-
packet_rx_md.tcp__mss, config.INTERFACE__TAP__MTU - 40
945+
packet_rx_md.tcp__mss, INTERFACE__TAP__MTU - 40
944946
)
945947
self._snd_wnd = (
946948
packet_rx_md.tcp__win << self._snd_wsc

0 commit comments

Comments
 (0)