예제 #1
0
  def CheckTCPConnection(self, mode, listensocket, netid, version,
                         myaddr, remoteaddr, packet, reply, msg):
    establishing_ack = packets.ACK(version, remoteaddr, myaddr, reply)[1]

    # Attempt to confuse the kernel.
    self.InvalidateDstCache(version, remoteaddr, netid)

    self.ReceivePacketOn(netid, establishing_ack)

    # If we're using UID routing, the accept() call has to be run as a UID that
    # is routed to the specified netid, because the UID of the socket returned
    # by accept() is the effective UID of the process that calls it. It doesn't
    # need to be the same UID; any UID that selects the same interface will do.
    with net_test.RunAsUid(self.UidForNetid(netid)):
      s, _ = listensocket.accept()

    try:
      # Check that data sent on the connection goes out on the right interface.
      desc, data = packets.ACK(version, myaddr, remoteaddr, establishing_ack,
                               payload=UDP_PAYLOAD)
      s.send(UDP_PAYLOAD)
      self.ExpectPacketOn(netid, msg + ": expecting %s" % desc, data)
      self.InvalidateDstCache(version, remoteaddr, netid)

      # Keep up our end of the conversation.
      ack = packets.ACK(version, remoteaddr, myaddr, data)[1]
      self.InvalidateDstCache(version, remoteaddr, netid)
      self.ReceivePacketOn(netid, ack)

      mark = self.GetSocketMark(s)
    finally:
      self.InvalidateDstCache(version, remoteaddr, netid)
      s.close()
      self.InvalidateDstCache(version, remoteaddr, netid)

    if mode == self.MODE_INCOMING_MARK:
      self.assertEquals(netid, mark,
                        msg + ": Accepted socket: Expected mark %d, got %d" % (
                            netid, mark))
    elif mode != self.MODE_EXPLICIT_MARK:
      self.assertEquals(0, self.GetSocketMark(listensocket))

    # Check the FIN was sent on the right interface, and ack it. We don't expect
    # this to fail because by the time the connection is established things are
    # likely working, but a) extra tests are always good and b) extra packets
    # like the FIN (and retransmitted FINs) could cause later tests that expect
    # no packets to fail.
    desc, fin = packets.FIN(version, myaddr, remoteaddr, ack)
    self.ExpectPacketOn(netid, msg + ": expecting %s after close" % desc, fin)

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

    # Since we called close() earlier, the userspace socket object is gone, so
    # the socket has no UID. If we're doing UID routing, the ack might be routed
    # incorrectly. Not much we can do here.
    desc, finackack = packets.ACK(version, myaddr, remoteaddr, finack)
    self.ExpectPacketOn(netid, msg + ": expecting final ack", finackack)
예제 #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()
예제 #3
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)
예제 #4
0
 def FinPacket(self):
     return packets.FIN(self.version, self.myaddr, self.remoteaddr,
                        self.last_packet)