def _CheckTunnelOutput(self, inner_version, outer_version): """Test a bi-directional XFRM Tunnel with explicit selectors""" # Select the underlying netid, which represents the external # interface from/to which to route ESP packets. underlying_netid = self.RandomNetid() # Select a random netid that will originate traffic locally and # which represents the logical tunnel network. netid = self.RandomNetid(exclude=underlying_netid) local_inner = self.MyAddress(inner_version, netid) remote_inner = _GetRemoteInnerAddress(inner_version) local_outer = self.MyAddress(outer_version, underlying_netid) remote_outer = _GetRemoteOuterAddress(outer_version) self.xfrm.CreateTunnel(xfrm.XFRM_POLICY_OUT, xfrm.SrcDstSelector(local_inner, remote_inner), local_outer, remote_outer, _TEST_OUT_SPI, xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1, None, underlying_netid) write_sock = socket(net_test.GetAddressFamily(inner_version), SOCK_DGRAM, 0) # Select an interface, which provides the source address of the inner # packet. self.SelectInterface(write_sock, netid, "mark") write_sock.sendto(net_test.UDP_PAYLOAD, (remote_inner, 53)) self._ExpectEspPacketOn(underlying_netid, _TEST_OUT_SPI, 1, None, local_outer, remote_outer)
def _CheckUpdatePolicy(self, version): """Tests that we can can update the template on a policy.""" family = net_test.GetAddressFamily(version) tmpl1 = xfrm.UserTemplate(family, 0xdead, 0, None) tmpl2 = xfrm.UserTemplate(family, 0xbeef, 0, None) sel = xfrm.EmptySelector(family) policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) mark = xfrm.XfrmMark(mark=0xf00, mask=xfrm_base.MARK_MASK_ALL) def _CheckTemplateMatch(tmpl): """Dump the SPD and match a single template on a single policy.""" dump = self.xfrm.DumpPolicyInfo() self.assertEquals(1, len(dump)) _, attributes = dump[0] self.assertEquals(attributes['XFRMA_TMPL'], tmpl) # Create a new policy using update. self.xfrm.UpdatePolicyInfo(policy, tmpl1, mark) # NEWPOLICY will not update the existing policy. This checks both that # UPDPOLICY created a policy and that NEWPOLICY will not perform updates. _CheckTemplateMatch(tmpl1) with self.assertRaisesErrno(EEXIST): self.xfrm.AddPolicyInfo(policy, tmpl2, mark) # Update the policy using UPDPOLICY. self.xfrm.UpdatePolicyInfo(policy, tmpl2, mark) # There should only be one policy after update, and it should have the # updated template. _CheckTemplateMatch(tmpl2)
def _TestSocketPolicyDstCache(self, version): """Test that destination cache is cleared with socket policy. This relies on the fact that connect() on a UDP socket populates the destination cache. """ # Create UDP socket. family = net_test.GetAddressFamily(version) netid = self.RandomNetid() s = socket(family, SOCK_DGRAM, 0) self.SelectInterface(s, netid, "mark") # Populate the socket's destination cache. remote = self.GetRemoteAddress(version) s.connect((remote, 53)) # Apply a policy to the socket. Should clear dst cache. reqid = 123 xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_OUT, TEST_SPI, reqid, None) # Policy with no matching SA should result in EAGAIN. If destination cache # failed to clear, then the UDP packet will be sent normally. with self.assertRaisesErrno(EAGAIN): s.send(net_test.UDP_PAYLOAD) self.ExpectNoPacketsOn(netid, "Packet not blocked by policy")
def _CheckNullEncryptionTunnelMode(self, version): family = net_test.GetAddressFamily(version) netid = self.RandomNetid() local_addr = self.MyAddress(version, netid) remote_addr = self.GetRemoteAddress(version) # Borrow the address of another netId as the source address of the tunnel tun_local = self.MyAddress(version, self.RandomNetid(netid)) # For generality, pick a tunnel endpoint that's not the address we # connect the socket to. tun_remote = TUNNEL_ENDPOINTS[version] # Output self.xfrm.AddSaInfo(tun_local, tun_remote, 0xABCD, xfrm.XFRM_MODE_TUNNEL, 123, xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, None, None, None, netid) # Input self.xfrm.AddSaInfo(tun_remote, tun_local, 0x9876, xfrm.XFRM_MODE_TUNNEL, 456, xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, None, None, None, None) sock = net_test.UDPSocket(family) self.SelectInterface(sock, netid, "mark") sock.bind((local_addr, 0)) local_port = sock.getsockname()[1] remote_port = 5555 xfrm_base.ApplySocketPolicy(sock, family, xfrm.XFRM_POLICY_OUT, 0xABCD, 123, (tun_local, tun_remote)) xfrm_base.ApplySocketPolicy(sock, family, xfrm.XFRM_POLICY_IN, 0x9876, 456, (tun_remote, tun_local)) # Create and receive an ESP packet. IpType = {4: scapy.IP, 6: scapy.IPv6}[version] input_pkt = (IpType(src=remote_addr, dst=local_addr) / scapy.UDP(sport=remote_port, dport=local_port) / "input hello") input_pkt = IpType(str(input_pkt)) # Compute length, checksum. input_pkt = xfrm_base.EncryptPacketWithNull(input_pkt, 0x9876, 1, (tun_remote, tun_local)) self.ReceivePacketOn(netid, input_pkt) msg, addr = sock.recvfrom(1024) self.assertEquals("input hello", msg) self.assertEquals((remote_addr, remote_port), addr[:2]) # Send and capture a packet. sock.sendto("output hello", (remote_addr, remote_port)) packets = self.ReadAllPacketsOn(netid) self.assertEquals(1, len(packets)) output_pkt = packets[0] output_pkt, esp_hdr = xfrm_base.DecryptPacketWithNull(output_pkt) self.assertEquals(output_pkt[scapy.UDP].len, len("output_hello") + 8) self.assertEquals(remote_addr, output_pkt.dst) self.assertEquals(remote_port, output_pkt[scapy.UDP].dport) # length of the payload plus the UDP header self.assertEquals("output hello", str(output_pkt[scapy.UDP].payload)) self.assertEquals(0xABCD, esp_hdr.spi)
def _SendPacket(testInstance, netid, version, remote, remote_port): # Send a packet out via the tunnel-backed network, bound for the port number # of the input socket. write_sock = socket(net_test.GetAddressFamily(version), SOCK_DGRAM, 0) testInstance.SelectInterface(write_sock, netid, "mark") write_sock.sendto(net_test.UDP_PAYLOAD, (remote, remote_port)) local_port = write_sock.getsockname()[1] return local_port
def _NlAttrTcpMetricsAddr(self, address, is_source): version = net_test.GetAddressVersion(address) family = net_test.GetAddressFamily(version) if version == 5: address = address.replace("::ffff:", "") nla_name = "TCP_METRICS_ATTR_%s_IPV%d" % ("SADDR" if is_source else "ADDR", version) nla_type = globals()[nla_name] return self._NlAttrIPAddress(nla_type, family, address)
def _CreateReceiveSock(version, port=0): # Create a socket to receive packets. read_sock = socket(net_test.GetAddressFamily(version), SOCK_DGRAM, 0) read_sock.bind((net_test.GetWildcardAddress(version), port)) # The second parameter of the tuple is the port number regardless of AF. local_port = read_sock.getsockname()[1] # Guard against the eventuality of the receive failing. net_test.SetNonBlocking(read_sock.fileno()) return read_sock, local_port
def _CheckPolicyDifferByDirection(self, version): """Tests that policies can differ only by direction.""" family = net_test.GetAddressFamily(version) tmpl = xfrm.UserTemplate(family, 0xdead, 0, None) sel = xfrm.EmptySelector(family) mark = xfrm.XfrmMark(mark=0xf00, mask=xfrm_base.MARK_MASK_ALL) policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) self.xfrm.AddPolicyInfo(policy, tmpl, mark) policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_IN, sel) self.xfrm.AddPolicyInfo(policy, tmpl, mark)
def SrcDstSelector(src, dst): """A selector that matches packets between the specified IP addresses.""" srcver = csocket.AddressVersion(src) dstver = csocket.AddressVersion(dst) if srcver != dstver: raise ValueError("Cross-address family selector specified: %s -> %s" % (src, dst)) prefixlen = net_test.AddressLengthBits(srcver) family = net_test.GetAddressFamily(srcver) return XfrmSelector(saddr=PaddedAddress(src), daddr=PaddedAddress(dst), prefixlen_s=prefixlen, prefixlen_d=prefixlen, family=family)
def _CheckTunnelModeOutputMark(self, version, tunsrc, mark, expected_netid): """Tests sending UDP packets to tunnel mode SAs with output marks. Opens a UDP socket and binds it to a random netid, then sets up tunnel mode SAs with an output_mark of mark and sets a socket policy to use the SA. Then checks that sending on those SAs sends a packet on expected_netid, or, if expected_netid is zero, checks that sending returns ENETUNREACH. Args: version: 4 or 6. tunsrc: A string, the source address of the tunnel. mark: An integer, the output_mark to set in the SA. expected_netid: An integer, the netid to expect the kernel to send the packet on. If None, expect that sendto will fail with ENETUNREACH. """ # Open a UDP socket and bind it to a random netid. family = net_test.GetAddressFamily(version) s = socket(family, SOCK_DGRAM, 0) self.SelectInterface(s, self.RandomNetid(), "mark") # For generality, pick a tunnel endpoint that's not the address we # connect the socket to. tundst = TUNNEL_ENDPOINTS[version] tun_addrs = (tunsrc, tundst) # Create a tunnel mode SA and use XFRM_OUTPUT_MARK to bind it to netid. spi = TEST_SPI * mark reqid = 100 + spi self.xfrm.AddSaInfo(tunsrc, tundst, spi, xfrm.XFRM_MODE_TUNNEL, reqid, xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1, None, None, None, mark) # Set a socket policy to use it. xfrm_base.ApplySocketPolicy(s, family, xfrm.XFRM_POLICY_OUT, spi, reqid, tun_addrs) # Send a packet and check that we see it on the wire. remoteaddr = self.GetRemoteAddress(version) packetlen = xfrm_base.GetEspPacketLength(xfrm.XFRM_MODE_TUNNEL, version, False, net_test.UDP_PAYLOAD, xfrm_base._ALGO_HMAC_SHA1, xfrm_base._ALGO_CBC_AES_256) if expected_netid is not None: s.sendto(net_test.UDP_PAYLOAD, (remoteaddr, 53)) self._ExpectEspPacketOn(expected_netid, spi, 1, packetlen, tunsrc, tundst) else: with self.assertRaisesErrno(ENETUNREACH): s.sendto(net_test.UDP_PAYLOAD, (remoteaddr, 53))
def _CheckGlobalPoliciesByMark(self, version): """Tests that global policies may differ by only the mark.""" family = net_test.GetAddressFamily(version) sel = xfrm.EmptySelector(family) # Pick 2 arbitrary mark values. mark1 = xfrm.XfrmMark(mark=0xf00, mask=xfrm_base.MARK_MASK_ALL) mark2 = xfrm.XfrmMark(mark=0xf00d, mask=xfrm_base.MARK_MASK_ALL) # Create a global policy. policy = xfrm.UserPolicy(xfrm.XFRM_POLICY_OUT, sel) tmpl = xfrm.UserTemplate(AF_UNSPEC, 0xfeed, 0, None) # Create the policy with the first mark. self.xfrm.AddPolicyInfo(policy, tmpl, mark1) # Create the same policy but with the second (different) mark. self.xfrm.AddPolicyInfo(policy, tmpl, mark2) # Delete the policies individually self.xfrm.DeletePolicyInfo(sel, xfrm.XFRM_POLICY_OUT, mark1) self.xfrm.DeletePolicyInfo(sel, xfrm.XFRM_POLICY_OUT, mark2)
def CreateTunnel(self, direction, selector, src, dst, spi, encryption, auth_trunc, mark, output_mark, xfrm_if_id): """Create an XFRM Tunnel Consisting of a Policy and an SA. Create a unidirectional XFRM tunnel, which entails one Policy and one security association. Args: direction: XFRM_POLICY_IN or XFRM_POLICY_OUT selector: An XfrmSelector that specifies the packets to be transformed. This is only applied to the policy; the selector in the SA is always empty. If the passed-in selector is None, then the tunnel is made dual-stack. This requires two policies, one for IPv4 and one for IPv6. src: The source address of the tunneled packets dst: The destination address of the tunneled packets spi: The SPI for the IPsec SA that encapsulates the tunneled packet encryption: A tuple (XfrmAlgo, key), the encryption parameters. auth_trunc: A tuple (XfrmAlgoAuth, key), the authentication parameters. mark: An XfrmMark, the mark used for selecting packets to be tunneled, and for matching the security policy and security association. None means unspecified. output_mark: The mark used to select the underlying network for packets outbound from xfrm. None means unspecified. xfrm_if_id: The ID of the XFRM interface to use or None. """ outer_family = net_test.GetAddressFamily(net_test.GetAddressVersion(dst)) self.AddSaInfo(src, dst, spi, XFRM_MODE_TUNNEL, 0, encryption, auth_trunc, None, None, mark, output_mark, xfrm_if_id=xfrm_if_id) if selector is None: selectors = [EmptySelector(AF_INET), EmptySelector(AF_INET6)] else: selectors = [selector] for selector in selectors: policy = UserPolicy(direction, selector) tmpl = UserTemplate(outer_family, spi, 0, (src, dst)) self.AddPolicyInfo(policy, tmpl, mark, xfrm_if_id=xfrm_if_id)
def _TestTunnel(self, inner_version, outer_version, func, direction): """Test a unidirectional XFRM Tunnel with explicit selectors""" # Select the underlying netid, which represents the external # interface from/to which to route ESP packets. u_netid = self.RandomNetid() # Select a random netid that will originate traffic locally and # which represents the netid on which the plaintext is sent netid = self.RandomNetid(exclude=u_netid) local_inner = self.MyAddress(inner_version, netid) remote_inner = _GetRemoteInnerAddress(inner_version) local_outer = self.MyAddress(outer_version, u_netid) remote_outer = _GetRemoteOuterAddress(outer_version) # Create input/ouput SPs, SAs and sockets to simulate a more realistic # environment. self.xfrm.CreateTunnel(xfrm.XFRM_POLICY_IN, xfrm.SrcDstSelector(remote_inner, local_inner), remote_outer, local_outer, _TEST_IN_SPI, xfrm_base._ALGO_CRYPT_NULL, xfrm_base._ALGO_AUTH_NULL, None, None, None) self.xfrm.CreateTunnel(xfrm.XFRM_POLICY_OUT, xfrm.SrcDstSelector(local_inner, remote_inner), local_outer, remote_outer, _TEST_OUT_SPI, xfrm_base._ALGO_CBC_AES_256, xfrm_base._ALGO_HMAC_SHA1, None, u_netid, None) write_sock = socket(net_test.GetAddressFamily(inner_version), SOCK_DGRAM, 0) self.SelectInterface(write_sock, netid, "mark") read_sock, _ = _CreateReceiveSock(inner_version) sock = write_sock if direction == xfrm.XFRM_POLICY_OUT else read_sock func(inner_version, outer_version, u_netid, netid, local_inner, remote_inner, local_outer, remote_outer, sock)
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 _CheckVtiInputOutput(self, vti, inner_version): local_outer = vti.local remote_outer = vti.remote # Create a socket to receive packets. read_sock = socket(net_test.GetAddressFamily(inner_version), SOCK_DGRAM, 0) read_sock.bind((net_test.GetWildcardAddress(inner_version), 0)) # The second parameter of the tuple is the port number regardless of AF. port = read_sock.getsockname()[1] # Guard against the eventuality of the receive failing. csocket.SetSocketTimeout(read_sock, 100) # Send a packet out via the vti-backed network, bound for the port number # of the input socket. write_sock = socket(net_test.GetAddressFamily(inner_version), SOCK_DGRAM, 0) self.SelectInterface(write_sock, vti.netid, "mark") write_sock.sendto(net_test.UDP_PAYLOAD, (_GetRemoteInnerAddress(inner_version), port)) # Read a tunneled IP packet on the underlying (outbound) network # verifying that it is an ESP packet. self.assertSentPacket(vti) pkt = self._ExpectEspPacketOn(vti.underlying_netid, vti.out_spi, vti.tx, None, local_outer, remote_outer) # Perform an address switcheroo so that the inner address of the remote # end of the tunnel is now the address on the local VTI interface; this # way, the twisted inner packet finds a destination via the VTI once # decrypted. remote = _GetRemoteInnerAddress(inner_version) local = vti.addrs[inner_version] self._SwapInterfaceAddress(vti.iface, new_addr=remote, old_addr=local) try: # Swap the packet's IP headers and write it back to the # underlying network. pkt = TunTwister.TwistPacket(pkt) self.ReceivePacketOn(vti.underlying_netid, pkt) self.assertReceivedPacket(vti) # Receive the decrypted packet on the dest port number. read_packet = read_sock.recv(4096) self.assertEquals(read_packet, net_test.UDP_PAYLOAD) finally: # Unwind the switcheroo self._SwapInterfaceAddress(vti.iface, new_addr=local, old_addr=remote) # Now attempt to provoke an ICMP error. # TODO: deduplicate with multinetwork_test.py. version = net_test.GetAddressVersion(vti.remote) dst_prefix, intermediate = { 4: ("172.19.", "172.16.9.12"), 6: ("2001:db8::", "2001:db8::1") }[version] write_sock.sendto(net_test.UDP_PAYLOAD, (_GetRemoteInnerAddress(inner_version), port)) self.assertSentPacket(vti) pkt = self._ExpectEspPacketOn(vti.underlying_netid, vti.out_spi, vti.tx, None, local_outer, remote_outer) myaddr = self.MyAddress(version, vti.underlying_netid) _, toobig = packets.ICMPPacketTooBig(version, intermediate, myaddr, pkt) self.ReceivePacketOn(vti.underlying_netid, toobig) # Check that the packet too big reduced the MTU. routes = self.iproute.GetRoutes(vti.remote, 0, vti.underlying_netid, None) self.assertEquals(1, len(routes)) rtmsg, attributes = routes[0] self.assertEquals(iproute.RTN_UNICAST, rtmsg.type) self.assertEquals(packets.PTB_MTU, attributes["RTA_METRICS"]["RTAX_MTU"]) # Clear PMTU information so that future tests don't have to worry about it. self.InvalidateDstCache(version, vti.underlying_netid)
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
def _TestSocketPolicy(self, version): # Open a UDP socket and connect it. family = net_test.GetAddressFamily(version) s = socket(family, SOCK_DGRAM, 0) netid = self.RandomNetid() self.SelectInterface(s, netid, "mark") remotesockaddr = self.GetRemoteSocketAddress(version) s.connect((remotesockaddr, 53)) saddr, sport = s.getsockname()[:2] daddr, dport = s.getpeername()[:2] if version == 5: saddr = saddr.replace("::ffff:", "") daddr = daddr.replace("::ffff:", "") reqid = 0 desc, pkt = packets.UDP(version, saddr, daddr, sport=sport) s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) self.ExpectPacketOn(netid, "Send after socket, expected %s" % desc, pkt) # Using IPv4 XFRM on a dual-stack socket requires setting an AF_INET policy # that's written in terms of IPv4 addresses. xfrm_version = 4 if version == 5 else version xfrm_family = net_test.GetAddressFamily(xfrm_version) xfrm_base.ApplySocketPolicy(s, xfrm_family, xfrm.XFRM_POLICY_OUT, TEST_SPI, reqid, None) # Because the policy has level set to "require" (the default), attempting # to send a packet results in an error, because there is no SA that # matches the socket policy we set. self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD, (remotesockaddr, 53)) # Adding a matching SA causes the packet to go out encrypted. The SA's # SPI must match the one in our template, and the destination address must # match the packet's destination address (in tunnel mode, it has to match # the tunnel destination). self.CreateNewSa(net_test.GetWildcardAddress(xfrm_version), self.GetRemoteAddress(xfrm_version), TEST_SPI, reqid, None) s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) expected_length = xfrm_base.GetEspPacketLength( xfrm.XFRM_MODE_TRANSPORT, version, False, net_test.UDP_PAYLOAD, xfrm_base._ALGO_HMAC_SHA1, xfrm_base._ALGO_CBC_AES_256) self._ExpectEspPacketOn(netid, TEST_SPI, 1, expected_length, None, None) # Sending to another destination doesn't work: again, no matching SA. remoteaddr2 = self.GetOtherRemoteSocketAddress(version) self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD, (remoteaddr2, 53)) # Sending on another socket without the policy applied results in an # unencrypted packet going out. s2 = socket(family, SOCK_DGRAM, 0) self.SelectInterface(s2, netid, "mark") s2.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) pkts = self.ReadAllPacketsOn(netid) self.assertEquals(1, len(pkts)) packet = pkts[0] protocol = packet.nh if version == 6 else packet.proto self.assertEquals(IPPROTO_UDP, protocol) # Deleting the SA causes the first socket to return errors again. self.xfrm.DeleteSaInfo(self.GetRemoteAddress(xfrm_version), TEST_SPI, IPPROTO_ESP) self.assertRaisesErrno(EAGAIN, s.sendto, net_test.UDP_PAYLOAD, (remotesockaddr, 53)) # Clear the socket policy and expect a cleartext packet. xfrm_base.SetPolicySockopt(s, family, None) s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) self.ExpectPacketOn(netid, "Send after clear, expected %s" % desc, pkt) # Clearing the policy twice is safe. xfrm_base.SetPolicySockopt(s, family, None) s.sendto(net_test.UDP_PAYLOAD, (remotesockaddr, 53)) self.ExpectPacketOn(netid, "Send after clear 2, expected %s" % desc, pkt) # Clearing if a policy was never set is safe. s = socket(AF_INET6, SOCK_DGRAM, 0) xfrm_base.SetPolicySockopt(s, family, None)