Beispiel #1
0
    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)
Beispiel #2
0
    def CheckForwardingCrash(self, netid, iface1, iface2):
        listenport = packets.RandomPort()
        listensocket = net_test.IPv6TCPSocket()
        listensocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        listensocket.bind(("::", listenport))
        listensocket.listen(100)
        self.SetSocketMark(listensocket, netid)

        version = 6
        remoteaddr = self.GetRemoteAddress(version)
        myaddr = self.MyAddress(version, netid)

        desc, syn = packets.SYN(listenport, version, remoteaddr, myaddr)
        synack_desc, synack = packets.SYNACK(version, myaddr, remoteaddr, syn)
        msg = "Sent %s, expected %s" % (desc, synack_desc)
        reply = self._ReceiveAndExpectResponse(netid, syn, synack, msg)

        establishing_ack = packets.ACK(version, remoteaddr, myaddr, reply)[1]
        self.ReceivePacketOn(netid, establishing_ack)
        accepted, peer = listensocket.accept()
        remoteport = accepted.getpeername()[1]

        accepted.close()
        desc, fin = packets.FIN(version, myaddr, remoteaddr, establishing_ack)
        self.ExpectPacketOn(netid, msg + ": expecting %s after close" % desc,
                            fin)

        desc, finack = packets.FIN(version, remoteaddr, myaddr, fin)
        self.ReceivePacketOn(netid, finack)

        # Check our socket is now in TIME_WAIT.
        sockets = self.ReadProcNetSocket("tcp6")
        mysrc = "%s:%04X" % (net_test.FormatSockStatAddress(myaddr),
                             listenport)
        mydst = "%s:%04X" % (net_test.FormatSockStatAddress(remoteaddr),
                             remoteport)
        state = None
        sockets = [s for s in sockets if s[0] == mysrc and s[1] == mydst]
        self.assertEquals(1, len(sockets))
        self.assertEquals("%02X" % self.TCP_TIME_WAIT, sockets[0][2])

        # Remove our IP address.
        try:
            self.iproute.DelAddress(myaddr, 64, self.ifindices[netid])

            self.ReceivePacketOn(iface1, finack)
            self.ReceivePacketOn(iface1, establishing_ack)
            self.ReceivePacketOn(iface1, establishing_ack)
            # No crashes? Good.

        finally:
            # Put back our IP address.
            self.SendRA(netid)
            listensocket.close()
Beispiel #3
0
    def CheckTCP(self, version, modes):
        """Checks that incoming TCP connections work.

    Args:
      version: An integer, 4 or 6.
      modes: A list of modes to excercise.
    """
        for syncookies in [0, 2]:
            for mode in modes:
                for netid, iif, ip_if, myaddr, remoteaddr in self.Combinations(
                        version):
                    if mode == self.MODE_UID:
                        listensocket = self.BuildSocket(
                            6, net_test.TCPSocket, netid, mode)
                        listensocket.listen(100)
                    else:
                        listensocket = self.listensocket

                    listenport = listensocket.getsockname()[1]

                    accept_sysctl = 1 if mode == self.MODE_INCOMING_MARK else 0
                    self._SetTCPMarkAcceptSysctl(accept_sysctl)

                    bound_dev = iif if mode == self.MODE_BINDTODEVICE else None
                    self.BindToDevice(listensocket, bound_dev)

                    mark = netid if mode == self.MODE_EXPLICIT_MARK else 0
                    self.SetSocketMark(listensocket, mark)

                    # Generate the packet here instead of in the outer loop, so
                    # subsequent TCP connections use different source ports and
                    # retransmissions from old connections don't confuse subsequent
                    # tests.
                    desc, packet = packets.SYN(listenport, version, remoteaddr,
                                               myaddr)

                    if mode:
                        reply_desc, reply = packets.SYNACK(
                            version, myaddr, remoteaddr, packet)
                    else:
                        reply_desc, reply = None, None

                    extra = "mode=%s, syncookies=%d" % (mode, syncookies)
                    msg = self._FormatMessage(iif, ip_if, extra, desc,
                                              reply_desc)
                    reply = self._ReceiveAndExpectResponse(
                        netid, packet, reply, msg)
                    if reply:
                        self.CheckTCPConnection(mode, listensocket, netid,
                                                version, myaddr, remoteaddr,
                                                packet, reply, msg)
  def CheckTCPSYNPacket(self, version, netid, routing_mode, dstaddr):
    s = self.BuildSocket(version, net_test.TCPSocket, netid, routing_mode)

    if version == 6 and dstaddr.startswith("::ffff"):
      version = 4
    myaddr = self.MyAddress(version, netid)
    desc, expected = packets.SYN(53, version, myaddr, dstaddr,
                                 sport=None, seq=None)

    # Non-blocking TCP connects always return EINPROGRESS.
    self.assertRaisesErrno(errno.EINPROGRESS, s.connect, (dstaddr, 53))
    msg = "IPv%s TCP connect: expected %s on %s" % (
        version, desc, self.GetInterfaceName(netid))
    self.ExpectPacketOn(netid, msg, expected)
    s.close()
 def testConnectInterrupted(self):
   """Tests that connect() is interrupted by SOCK_DESTROY."""
   for version in [4, 5, 6]:
     family = {4: AF_INET, 5: AF_INET6, 6: AF_INET6}[version]
     s = net_test.Socket(family, SOCK_STREAM, IPPROTO_TCP)
     self.SelectInterface(s, self.netid, "mark")
     if version == 5:
       remoteaddr = "::ffff:" + self.GetRemoteAddress(4)
       version = 4
     else:
       remoteaddr = self.GetRemoteAddress(version)
     s.bind(("", 0))
     _, sport = s.getsockname()[:2]
     self.CloseDuringBlockingCall(
         s, lambda sock: sock.connect((remoteaddr, 53)), ECONNABORTED)
     desc, syn = packets.SYN(53, version, self.MyAddress(version, self.netid),
                             remoteaddr, sport=sport, seq=None)
     self.ExpectPacketOn(self.netid, desc, syn)
     msg = "SOCK_DESTROY of socket in connect, expected no RST"
     self.ExpectNoPacketsOn(self.netid, msg)
 def SYNToClosedPort(self, *args):
   return packets.SYN(999, *args)
Beispiel #7
0
    def CheckConnectOption(self, version):
        ip_layer = {4: scapy.IP, 6: scapy.IPv6}[version]
        netid = self.RandomNetid()
        s = self.TFOClientSocket(version, netid)

        self.clearTcpMetrics(version, netid)

        # Connect the first time.
        remoteaddr = self.GetRemoteAddress(version)
        with self.assertRaisesErrno(EINPROGRESS):
            s.connect((remoteaddr, 53))
        self.assertSocketNotConnected(s)

        # Expect a SYN handshake with an empty TFO option.
        myaddr = self.MyAddress(version, netid)
        port = s.getsockname()[1]
        self.assertNotEqual(0, port)
        desc, syn = packets.SYN(53,
                                version,
                                myaddr,
                                remoteaddr,
                                port,
                                seq=None)
        syn.getlayer("TCP").options = [(TCPOPT_FASTOPEN, "")]
        msg = "Fastopen connect: expected %s" % desc
        syn = self.ExpectPacketOn(netid, msg, syn)
        syn = ip_layer(str(syn))

        # Receive a SYN+ACK with a TFO cookie and expect the connection to proceed
        # as normal.
        desc, synack = packets.SYNACK(version, remoteaddr, myaddr, syn)
        synack.getlayer("TCP").options = [(TCPOPT_FASTOPEN, "helloT"),
                                          ("NOP", None), ("NOP", None)]
        self.ReceivePacketOn(netid, synack)
        synack = ip_layer(str(synack))
        desc, ack = packets.ACK(version, myaddr, remoteaddr, synack)
        msg = "First connect: got SYN+ACK, expected %s" % desc
        self.ExpectPacketOn(netid, msg, ack)
        self.assertSocketConnected(s)
        s.close()
        desc, rst = packets.RST(version, myaddr, remoteaddr, synack)
        msg = "Closing client socket, expecting %s" % desc
        self.ExpectPacketOn(netid, msg, rst)

        # Connect to the same destination again. Expect the connect to succeed
        # without sending a SYN packet.
        s = self.TFOClientSocket(version, netid)
        s.connect((remoteaddr, 53))
        self.assertSocketNotConnected(s)
        self.ExpectNoPacketsOn(netid,
                               "Second TFO connect, expected no packets")

        # Issue a write and expect a SYN with data.
        port = s.getsockname()[1]
        s.send(net_test.UDP_PAYLOAD)
        desc, syn = packets.SYN(53,
                                version,
                                myaddr,
                                remoteaddr,
                                port,
                                seq=None)
        t = syn.getlayer(scapy.TCP)
        t.options = [(TCPOPT_FASTOPEN, "helloT"), ("NOP", None), ("NOP", None)]
        t.payload = scapy.Raw(net_test.UDP_PAYLOAD)
        msg = "TFO write, expected %s" % desc
        self.ExpectPacketOn(netid, msg, syn)