def IncomingConnection(self, version, end_state, netid): self.s = self.OpenListenSocket(version, netid) self.end_state = end_state remoteaddr = self.remoteaddr = self.GetRemoteAddress(version) remotesockaddr = self.remotesockaddr = self.GetRemoteSocketAddress( version) myaddr = self.myaddr = self.MyAddress(version, netid) mysockaddr = self.mysockaddr = self.MySocketAddress(version, netid) if version == 5: version = 4 self.version = version if end_state == TCP_LISTEN: return desc, syn = packets.SYN(self.port, version, remoteaddr, myaddr) synack_desc, synack = packets.SYNACK(version, myaddr, remoteaddr, syn) msg = "Received %s, expected to see reply %s" % (desc, synack_desc) reply = self._ReceiveAndExpectResponse(netid, syn, synack, msg) if end_state == TCP_SYN_RECV: return establishing_ack = packets.ACK(version, remoteaddr, myaddr, reply)[1] self.ReceivePacketOn(netid, establishing_ack) if end_state == TCP_NOT_YET_ACCEPTED: return self.accepted, _ = self.s.accept() net_test.DisableFinWait(self.accepted) if end_state == TCP_ESTABLISHED: return desc, data = packets.ACK(version, myaddr, remoteaddr, establishing_ack, payload=net_test.UDP_PAYLOAD) self.accepted.send(net_test.UDP_PAYLOAD) self.ExpectPacketOn(netid, msg + ": expecting %s" % desc, data) desc, fin = packets.FIN(version, remoteaddr, myaddr, data) fin = packets._GetIpLayer(version)(str(fin)) ack_desc, ack = packets.ACK(version, myaddr, remoteaddr, fin) msg = "Received %s, expected to see reply %s" % (desc, ack_desc) # TODO: Why can't we use this? # self._ReceiveAndExpectResponse(netid, fin, ack, msg) self.ReceivePacketOn(netid, fin) time.sleep(0.1) self.ExpectPacketOn(netid, msg + ": expecting %s" % ack_desc, ack) if end_state == TCP_CLOSE_WAIT: return raise ValueError("Invalid TCP state %d specified" % end_state)
def ParamTestSocketPolicySimple(self, params): """Test two-way traffic using transport mode and socket policies.""" def AssertEncrypted(packet): # This gives a free pass to ICMP and ICMPv6 packets, which show up # nondeterministically in tests. self.assertEquals(None, packet.getlayer(scapy.UDP), "UDP packet sent in the clear") self.assertEquals(None, packet.getlayer(scapy.TCP), "TCP packet sent in the clear") # We create a pair of sockets, "left" and "right", that will talk to each # other using transport mode ESP. Because of TapTwister, both sockets # perceive each other as owning "remote_addr". netid = self.RandomNetid() family = net_test.GetAddressFamily(params["version"]) local_addr = self.MyAddress(params["version"], netid) remote_addr = self.GetRemoteSocketAddress(params["version"]) crypt_left = (xfrm.XfrmAlgo( (params["crypt"].name, params["crypt"].key_len)), os.urandom(params["crypt"].key_len / 8)) if params["crypt"] else None crypt_right = (xfrm.XfrmAlgo( (params["crypt"].name, params["crypt"].key_len)), os.urandom(params["crypt"].key_len / 8)) if params["crypt"] else None auth_left = (xfrm.XfrmAlgoAuth( (params["auth"].name, params["auth"].key_len, params["auth"].trunc_len)), os.urandom(params["auth"].key_len / 8)) if params["auth"] else None auth_right = (xfrm.XfrmAlgoAuth( (params["auth"].name, params["auth"].key_len, params["auth"].trunc_len)), os.urandom(params["auth"].key_len / 8)) if params["auth"] else None aead_left = (xfrm.XfrmAlgoAead( (params["aead"].name, params["aead"].key_len, params["aead"].icv_len)), os.urandom(params["aead"].key_len / 8)) if params["aead"] else None aead_right = (xfrm.XfrmAlgoAead( (params["aead"].name, params["aead"].key_len, params["aead"].icv_len)), os.urandom(params["aead"].key_len / 8)) if params["aead"] else None spi_left = 0xbeefface spi_right = 0xcafed00d req_ids = [100, 200, 300, 400] # Used to match templates and SAs. # Left outbound SA self.xfrm.AddSaInfo(src=local_addr, dst=remote_addr, spi=spi_right, mode=xfrm.XFRM_MODE_TRANSPORT, reqid=req_ids[0], encryption=crypt_right, auth_trunc=auth_right, aead=aead_right, encap=None, mark=None, output_mark=None) # Right inbound SA self.xfrm.AddSaInfo(src=remote_addr, dst=local_addr, spi=spi_right, mode=xfrm.XFRM_MODE_TRANSPORT, reqid=req_ids[1], encryption=crypt_right, auth_trunc=auth_right, aead=aead_right, encap=None, mark=None, output_mark=None) # Right outbound SA self.xfrm.AddSaInfo(src=local_addr, dst=remote_addr, spi=spi_left, mode=xfrm.XFRM_MODE_TRANSPORT, reqid=req_ids[2], encryption=crypt_left, auth_trunc=auth_left, aead=aead_left, encap=None, mark=None, output_mark=None) # Left inbound SA self.xfrm.AddSaInfo(src=remote_addr, dst=local_addr, spi=spi_left, mode=xfrm.XFRM_MODE_TRANSPORT, reqid=req_ids[3], encryption=crypt_left, auth_trunc=auth_left, aead=aead_left, encap=None, mark=None, output_mark=None) # Make two sockets. sock_left = socket(family, params["proto"], 0) sock_left.settimeout(2.0) sock_left.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) self.SelectInterface(sock_left, netid, "mark") sock_right = socket(family, params["proto"], 0) sock_right.settimeout(2.0) sock_right.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) self.SelectInterface(sock_right, netid, "mark") # For UDP, set SO_LINGER to 0, to prevent TCP sockets from hanging around # in a TIME_WAIT state. if params["proto"] == SOCK_STREAM: net_test.DisableFinWait(sock_left) net_test.DisableFinWait(sock_right) # Apply the left outbound socket policy. xfrm_base.ApplySocketPolicy(sock_left, family, xfrm.XFRM_POLICY_OUT, spi_right, req_ids[0], None) # Apply right inbound socket policy. xfrm_base.ApplySocketPolicy(sock_right, family, xfrm.XFRM_POLICY_IN, spi_right, req_ids[1], None) # Apply right outbound socket policy. xfrm_base.ApplySocketPolicy(sock_right, family, xfrm.XFRM_POLICY_OUT, spi_left, req_ids[2], None) # Apply left inbound socket policy. xfrm_base.ApplySocketPolicy(sock_left, family, xfrm.XFRM_POLICY_IN, spi_left, req_ids[3], None) server_ready = threading.Event() server_error = None # Save exceptions thrown by the server. def TcpServer(sock, client_port): try: sock.listen(1) server_ready.set() accepted, peer = sock.accept() self.assertEquals(remote_addr, peer[0]) self.assertEquals(client_port, peer[1]) data = accepted.recv(2048) self.assertEquals("hello request", data) accepted.send("hello response") except Exception as e: server_error = e finally: sock.close() def UdpServer(sock, client_port): try: server_ready.set() data, peer = sock.recvfrom(2048) self.assertEquals(remote_addr, peer[0]) self.assertEquals(client_port, peer[1]) self.assertEquals("hello request", data) sock.sendto("hello response", peer) except Exception as e: server_error = e finally: sock.close() # Server and client need to know each other's port numbers in advance. wildcard_addr = net_test.GetWildcardAddress(params["version"]) sock_left.bind((wildcard_addr, 0)) sock_right.bind((wildcard_addr, 0)) left_port = sock_left.getsockname()[1] right_port = sock_right.getsockname()[1] # Start the appropriate server type on sock_right. target = TcpServer if params["proto"] == SOCK_STREAM else UdpServer server = threading.Thread(target=target, args=(sock_right, left_port), name="SocketServer") server.start() # Wait for server to be ready before attempting to connect. TCP retries # hide this problem, but UDP will fail outright if the server socket has # not bound when we send. self.assertTrue(server_ready.wait(2.0), "Timed out waiting for server thread") with TapTwister(fd=self.tuns[netid].fileno(), validator=AssertEncrypted): sock_left.connect((remote_addr, right_port)) sock_left.send("hello request") data = sock_left.recv(2048) self.assertEquals("hello response", data) sock_left.close() server.join() if server_error: raise server_error
def TFOClientSocket(self, version, netid): s = net_test.TCPSocket(net_test.GetAddressFamily(version)) net_test.DisableFinWait(s) self.SelectInterface(s, netid, "mark") s.setsockopt(IPPROTO_TCP, TCP_FASTOPEN_CONNECT, 1) return s