def write(cls, packet, remote_info, local_info): from core.sock import SockManager sock = SockManager.lookup_bidirectional_sock(Tcp.PROT_TYPE, local_info, remote_info) if sock is None: return Tcp.tcp_send_packet(sock, remote_info, local_info, ['psh', 'ack'], out_packet=packet) sock._snd_nxt += len(packet)
def tcp_send_syn(cls, packet, remote_info, local_info): from core.sock import SockManager sock = SockManager.lookup_bidirectional_sock(Tcp.PROT_TYPE, local_info, remote_info) if sock is None: return Tcp.tcp_send_packet(sock, remote_info, local_info, ['syn']) sock._snd_nxt += 1
def recv(cls, ipv4_packet): tcp_packet = TcpPacket(ipv4_packet.payload) tcp_packet.LOG("info", "TAKE") from core.sock import SockManager local_info = ipv4_packet.dst_ip_addr, tcp_packet.dst_port remote_info = ipv4_packet.src_ip_addr, tcp_packet.src_port sock = SockManager.lookup_bidirectional_sock(Tcp.PROT_TYPE, local_info, remote_info) if sock is None: sock = SockManager.lookup_unidirectional_sock(Tcp.PROT_TYPE, local_info) if sock is None: tcp_packet.LOG("error", "no sock") return sock = SockManager.register_bidirectional_sock(Tcp.PROT_TYPE, remote_info, local_info) sock.state = "TCP_LISTEN" sock.LOG("info", "START") Tcp.tcp_state_transform(sock, ipv4_packet, tcp_packet) sock.LOG("info", "FINISH")
async def connect(self, remote_info): if self._sock is not None: return remote_ip_addr, remote_port = remote_info remote_ip_addr = util.ip_s2i(remote_ip_addr) remote_info_int = remote_ip_addr, remote_port local_info_int = self._local_ip_addr_int, self._local_port self._sock = SockManager.lookup_bidirectional_sock( self._prot_type, local_info_int, remote_info_int) await self._sock.connect() return
def recv(cls, ipv4_packet): udp_packet = UdpPacket(ipv4_packet.payload) udp_packet.log("info", "TAKE") from core.sock import SockManager remote_info = ipv4_packet.src_ip_addr, udp_packet.src_port local_info = ipv4_packet.dst_ip_addr, udp_packet.dst_port sock = SockManager.lookup_unidirectional_sock(Udp.PROT_TYPE, remote_info, local_info) sock._remote_ip_addr = ipv4_packet.src_ip_addr sock._remote_port = udp_packet.src_port if sock is None: udp_packet.log("error", "NO SOCK") return sock.enqueue_data(udp_packet.payload)
def init_net_dev(route_addr, ip_addr, tap_name): tap = Tuntap(tap_name, ip_addr, route_addr) NetDevManager.register_net_dev(tap) SockManager.init()
def tcp_state_transform(cls, sock, ipv4_packet, tcp_packet): if tcp_packet.syn == 1: sock.seq = tcp_packet.seq_no sock.ack = tcp_packet.seq_no sock._snd_una = tcp_packet.seq_no sock._snd_nxt = tcp_packet.seq_no sock._rcv_nxt = tcp_packet.seq_no # handle ack if tcp_packet.ack == 1: sock._snd_una = max(sock._snd_una, tcp_packet.ack_no) sock.seq = max(sock.seq, tcp_packet.ack_no) if tcp_packet.syn == 1 or tcp_packet.psh == 1: # if tcp_packet.ack_no != sock.seq or tcp_packet.seq_no != sock.ack: # sock.LOG("error", "ACK SEQ NO ERROR") sock.ack += max(1, len(tcp_packet.payload)) sock._rcv_nxt += max(1, len(tcp_packet.payload)) local_info = ipv4_packet.dst_ip_addr, tcp_packet.dst_port remote_info = ipv4_packet.src_ip_addr, tcp_packet.src_port if sock.state == "TCP_LISTEN": # -> TCP_SYN_RECV tcp_packet.LOG("info", "TCP_LISTEN -> TCP_SYN_RECV") sock.LOG("info", "TCP_LISTEN -> TCP_SYN_RECV") Tcp.save_merge_options(sock, tcp_packet.option) Tcp.tcp_send_packet(sock, remote_info, local_info, ['syn', 'ack'], option=sock.option_bin) sock.state = "TCP_SYN_RECV" return if sock.state == "TCP_SYN_RECV": # -> TCP_ESTABLISHED tcp_packet.LOG("info", "TCP_SYN_RECV -> TCP_ESTABLISHED") sock.state = "TCP_ESTABLISHED" # enqueue acceptor from core.sock import SockManager local_info = sock.local_ip_addr, sock.local_port base_sock = SockManager.lookup_unidirectional_sock(Tcp.PROT_TYPE, local_info) base_sock.enqueue_acceptor(sock) return if sock.state == "TCP_SYN_SEND": # -> TCP_ESTABLISHED if tcp_packet.syn == 1 and tcp_packet.ack == 1: Tcp.tcp_send_packet(sock, remote_info, local_info, ['ack']) if sock.state in ["TCP_ESTABLISHED", "TCP_FIN_WAIT_1", "TCP_FIN_WAIT_2"]: # recv data if tcp_packet.psh == 1 and tcp_packet.ack == 1: sock.enqueue_data(tcp_packet.payload) Tcp.tcp_send_packet(sock, remote_info, local_info, ['ack']) return if sock.state == "TCP_FIN_WAIT_1": if tcp_packet.ack == 1: sock.state = "TCP_FIN_WAIT_2" return if sock.state == "TCP_FIN_WAIT_2": if tcp_packet.fin == 1: Tcp.tcp_send_packet(sock, remote_info, local_info, ['ack']) sock.state = "TCP_TIME_WAIT" return
def listen(self): self._sock = SockManager.register_unidirectional_sock( self._prot_type, (self._local_ip_addr_int, self._local_port)) return self._sock.listen()