Beispiel #1
0
    def connectToNodeServer(self):
        debug("Connecting to node server @ %s"%repr(self.nodeServer))
        while True:
            self.updateNodeState(NS_CONNECTING)
            if self.sock != None:
                self.sock.close()
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sockQueue = net_helpers.SocketQueue(self.sock)
            self.sockPacker = net_helpers.Packer()
            try:
                self.sock.connect(self.nodeServer)
                break
            except:
                debug("Connect failed, trying again in 5s...")
                self.updateNodeState(NS_FAILED)
            time.sleep(5)
        self.updateNodeState(NS_CONNECTED)
        debug("Connected.")

        # Reset last packet counter so we don't time out.
        self.lastPacketReceived = time.time()

        # send register packet
        debug("Registering with node server...")
        b = ByteStream()
        b.writeByte(P_REGISTER)
        self.send(b)
Beispiel #2
0
    def connectToNodeServer(self):
        debug("Connecting to node server @ %s" % repr(self.nodeServer))
        while True:
            self.updateNodeState(NS_CONNECTING)
            if self.sock != None:
                self.sock.close()
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sockQueue = net_helpers.SocketQueue(self.sock)
            self.sockPacker = net_helpers.Packer()
            try:
                self.sock.connect(self.nodeServer)
                break
            except:
                debug("Connect failed, trying again in 5s...")
                self.updateNodeState(NS_FAILED)
            time.sleep(5)
        self.updateNodeState(NS_CONNECTED)
        debug("Connected.")

        # Reset last packet counter so we don't time out.
        self.lastPacketReceived = time.time()

        # send register packet
        debug("Registering with node server...")
        b = ByteStream()
        b.writeByte(P_REGISTER)
        self.send(b)
Beispiel #3
0
 def sendRelayPacket(self, targetId, targetPort, data):
     """ Sends tunnel info to a node. """
     out = ByteStream()
     out.writeByte(P_RELAY_PACKET)
     out.writeString(targetId)
     out.writeString(targetPort)
     out.writeString(data)
     self.send(out)
Beispiel #4
0
 def sendConnectFailed(self, targetId, targetPort, errorCode):
     """ Sends the connection failed packet back to node. """
     out = ByteStream()
     out.writeByte(P_CONNECT_RESPONSE)
     out.writeString(targetId)
     out.writeString(targetPort)
     out.writeByte(errorCode)
     self.send(out)
Beispiel #5
0
 def sendConnectSuccess(self, targetId, targetPort):
     """ Sends the connection success packet back to node. """
     out = ByteStream()
     out.writeByte(P_CONNECT_RESPONSE)
     out.writeString(targetId)
     out.writeString(targetPort)
     out.writeByte(ERR_NO_ERROR)
     self.send(out)
Beispiel #6
0
def test_can_resume_reading_after_nothing_available():
    b = ByteStream()
    b.write(b"hello")
    b.read(5)
    read = b.read(1)
    assert read is None
    b.write(b"world")
    read = b.read(5)
    assert read.tobytes() == b"world"
Beispiel #7
0
 def reflectAddress(self):
     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     sock.sendto("", self.reflectionServer)
     privIp, privPort = sock.getsockname()
     data = sock.recv(128)
     sock.close()
     response = ByteStream(data)
     pubIp = response.readString()
     pubPort = response.readInt()
     return (privPort, pubIp, pubPort)
Beispiel #8
0
 def reflectAddress(self):
     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     sock.sendto('', self.reflectionServer)
     privIp, privPort = sock.getsockname()
     data = sock.recv(128)
     sock.close()
     response = ByteStream(data)
     pubIp = response.readString()
     pubPort = response.readInt()
     return (privPort, pubIp, pubPort)
Beispiel #9
0
    def thread():
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect(PARSER_SERVER_ADDR)
        except:
            prnt("Failed to connect:")
            prnt(traceback.format_exc())
            wx.CallAfter(failureFunc)
            return

        stream = ByteStream()
        stream.writeByte(pkt.GET_KEY)
        stream.writeString(vanityKey)
        sock.send(stream.toString())

        data = sock.recv(1024)
        sock.close()

        stream = ByteStream(data)

        success = stream.readByte() == 1
        if success:
            key = stream.readString()
            wx.CallAfter(successFunc, key)
        else:
            wx.CallAfter(failureFunc)
Beispiel #10
0
    def run(self):
        prnt("RaidServer: Booting up...")

        self.port = net.node.bind("swap:raid")

        self.centralSock.setblocking(False)
        while not self.stoppedEvent.isSet():
            now = time()

            # Central server
            r, w, e = select([self.centralSock], [self.centralSock], [], 0)
            if r:
                data = self.centralSock.recv(1024)
                stream = ByteStream(data)
                packetType = stream.readByte()

            if self.port.connectionPending():
                conn = self.port.accept()
                self.clientList.append({'conn': conn, 'playerInfo': None})

            for client in self.clientList:
                conn = client['conn']
                if conn.recvPending():
                    data = conn.recv()
                    if data == None:
                        playerName = client['playerInfo']['name'] if client[
                            'playerInfo'] else "<NoInfo>"
                        prnt("Client (%s) left raid, reason=%s" %
                             (playerName, fuzion.formatError(
                                 conn.closedReason)))
                        self.lastRaidUpdatePoke = time()
                        self.clientList.remove(client)
                        continue
                    packetType = data.readByte()
                    if packetType == pkt.PLAYER_UPDATE:
                        self.processPlayerUpdate(client, data)

            if now - self.lastRaidUpdateSent > 2 and now - self.lastRaidUpdatePoke < 5:
                self.sendRaidUpdate()
                self.lastRaidUpdateSent = now

            sleep(0.1)

        self.port.close()

        for client in self.clientList:
            conn = client['conn']
            conn.close()

        self.centralSock.close()

        prnt("RaidServer: Shutting down...")
 def setUp(self):
     self.HasUri = namedtuple('HasUri', ['uri'])
     self.bytestream = ByteStream(chunksize=3)
     self.port = '9876'
     path = os.path.dirname(__file__)
     server = os.path.join(path, 'dummyserver.py')
     self.expected = ''.join(uuid4().hex for _ in xrange(100))
     devnull = open(os.devnull, 'w')
     self.process = subprocess.Popen(
         [sys.executable, server, self.port, self.expected],
         stdout=devnull,
         stderr=devnull)
     time.sleep(0.1)
Beispiel #12
0
    def connect(self, targetId, targetPort):
        self.waitForNS()

        # Prevent connecting if there is already a outbound connection.
        if self.getConnection(targetId, targetPort, True):
            debug("Duplicate connection to %s:%s found."%(targetId, targetPort))
            # Yes, this may throw an error in the app, but they shouldn't
            # be creating duplicate connections anyway, so it doesn't matter.
            return None

        debug("Connecting to %s"%targetId)

        out = ByteStream()
        out.writeByte(P_CONNECT_REQUEST)
        out.writeString(targetId)
        out.writeString(targetPort)
        self.send(out)

        conn = NodeConnection(self, targetId, targetPort, True)
        conn.requestTime = time.time()
        self.connections.append(conn)

        while True:
            # Wait till connected.
            if conn.state == CS_CONNECTED or conn.state >= CS_FAILED_BASE:
                if conn.state == CS_FAILED_NO_NODE:
                    debug("Failed to connect: no such node")
                elif conn.state == CS_FAILED_REJECTED:
                    debug("Failed to connect: rejected")
                break
            time.sleep(0.1)

        return conn
Beispiel #13
0
 def sendConnectRequest(self, sourceId, targetPort):
     """ Sends the connection request from sourceId to this node. """
     out = ByteStream()
     out.writeByte(P_CONNECT_REQUEST)
     out.writeString(sourceId)
     out.writeString(targetPort)
     self.send(out)
Beispiel #14
0
    def run(self):
        prnt("RaidServer: Booting up...")

        self.port = net.node.bind("swap:raid")

        self.centralSock.setblocking(False)
        while not self.stoppedEvent.isSet():
            now = time()

            # Central server
            r, w, e = select([self.centralSock], [self.centralSock], [], 0)
            if r:
                data = self.centralSock.recv(1024)
                stream = ByteStream(data)
                packetType = stream.readByte()

            if self.port.connectionPending():
                conn = self.port.accept()
                self.clientList.append({ 'conn': conn, 'playerInfo': None })

            for client in self.clientList:
                conn = client['conn']
                if conn.recvPending():
                    data = conn.recv()
                    if data == None:
                        playerName = client['playerInfo']['name'] if client['playerInfo'] else "<NoInfo>"
                        prnt("Client (%s) left raid, reason=%s"%(playerName, fuzion.formatError(conn.closedReason)))
                        self.lastRaidUpdatePoke = time()
                        self.clientList.remove(client)
                        continue
                    packetType = data.readByte()
                    if packetType == pkt.PLAYER_UPDATE:
                        self.processPlayerUpdate(client, data)

            if now - self.lastRaidUpdateSent > 2 and now - self.lastRaidUpdatePoke < 5:
                self.sendRaidUpdate()
                self.lastRaidUpdateSent = now

            sleep(0.1)

        self.port.close()

        for client in self.clientList:
            conn = client['conn']
            conn.close()

        self.centralSock.close()

        prnt("RaidServer: Shutting down...")
Beispiel #15
0
    def closeInternal(self, reason):
        with self.closedLock:
            if self.closed:
                return
            if reason == ERR_CLOSED_BY_SELF:
                packet = ByteStream()
                packet.writeByte(P_CLOSE)
                self._send(packet.toString())

            self.threadStopped.set()
            self.node.connectionDied(self)
            self.closed = True
            self.closedReason = reason
            if not self.loopback and not self.relay:
                self.sock.close()
Beispiel #16
0
    def closeInternal(self, reason):
        with self.closedLock:
            if self.closed:
                return
            if reason == ERR_CLOSED_BY_SELF:
                packet = ByteStream()
                packet.writeByte(P_CLOSE)
                self._send(packet.toString())

            self.threadStopped.set()
            self.node.connectionDied(self)
            self.closed = True
            self.closedReason = reason
            if not self.loopback and not self.relay:
                self.sock.close()
Beispiel #17
0
def test_can_find_bytes_several_chunks_ahead():
    b = ByteStream()
    b.write(b"xxx")
    b.write(b"xxx")
    b.write(b"xxx")
    b.write(b"abc")
    distance = b.until(97)
    assert distance == 10
    distance = b.until(98)
    assert distance == 11
    distance = b.until(99)
    assert distance == 12
Beispiel #18
0
def test_can_write_several_then_read_across_boundaries():
    b = ByteStream()
    b.write(b"aaa")
    b.write(b"bbb")
    b.write(b"ccc")
    b.write(b"ddd")
    read = b.read(4)
    assert read.tobytes() == b"aaab"
    read = b.read(4)
    assert read.tobytes() == b"bbcc"
    read = b.read(4)
    assert read.tobytes() == b"cddd"
Beispiel #19
0
 def recv(self, raw=False):
     while len(self.pendingRecv) == 0 and not self.closed:
         time.sleep(0.1)
     if self.closed:
         return None
     data = self.pendingRecv.pop(0)
     return ByteStream(data) if not raw else data
Beispiel #20
0
    def __init__(self,filename):
        if filename == None: 
            raise(Exception("Null File Name."))        

        self.bs = ByteStream(filename)
        
        self._dex = dxlib.dx_parse(self.bs._bs)
Beispiel #21
0
    def test_can_accept_chunksize_implementing_int(self):
        class SemanticChunksize(object):
            THING_SIZE_BYTES = 64

            def __init__(self, n_things=10):
                self.n_things = n_things

            def __int__(self):
                return self.n_things * self.THING_SIZE_BYTES

        bs = ByteStream(chunksize=SemanticChunksize(n_things=100))
        bio = BytesIO()
        bio.write(os.urandom(int(1e5)))
        bio.seek(0)
        chunks = list(bs._process(bio))
        self.assertEqual(6400, len(chunks[0]))
Beispiel #22
0
    def connect(self, targetId, targetPort):
        self.waitForNS()

        # Prevent connecting if there is already a outbound connection.
        if self.getConnection(targetId, targetPort, True):
            debug("Duplicate connection to %s:%s found." % (targetId, targetPort))
            # Yes, this may throw an error in the app, but they shouldn't
            # be creating duplicate connections anyway, so it doesn't matter.
            return None

        debug("Connecting to %s" % targetId)

        out = ByteStream()
        out.writeByte(P_CONNECT_REQUEST)
        out.writeString(targetId)
        out.writeString(targetPort)
        self.send(out)

        conn = NodeConnection(self, targetId, targetPort, True)
        conn.requestTime = time.time()
        self.connections.append(conn)

        while True:
            # Wait till connected.
            if conn.state == CS_CONNECTED or conn.state >= CS_FAILED_BASE:
                if conn.state == CS_FAILED_NO_NODE:
                    debug("Failed to connect: no such node")
                elif conn.state == CS_FAILED_REJECTED:
                    debug("Failed to connect: rejected")
                break
            time.sleep(0.1)

        return conn
Beispiel #23
0
    def run(self):
        global PUBLIC_IP_UPDATE_LAST
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind(('', REFLECTION_SERVER_PORT))

        debug("Reflection Server listening on %d"%REFLECTION_SERVER_PORT)

        refreshPublicIP()
        PUBLIC_IP_UPDATE_LAST = time.time()

        while True:
            r, w, e = select([self.sock], [self.sock], [], 0)
            if r:
                data, addr = self.sock.recvfrom(1024)
                ip = addr[0]
                port = addr[1]
                if ip == SERVER_GATEWAY_IP:
                    ip = SERVER_PUBLIC_IP

                out = ByteStream()
                out.writeString(ip)
                out.writeInt(port)
                self.sock.sendto(out.toString(), addr)

            now = time.time()
            if now - PUBLIC_IP_UPDATE_LAST > PUBLIC_IP_UPDATE_INTERVAL:
                PUBLIC_IP_UPDATE_LAST = now
                threading.Thread(target=refreshPublicIP).start()

            time.sleep(0.01)
        self.sock.close()
Beispiel #24
0
def test_distance_only_measured_to_next_matching_byte():
    b = ByteStream()
    b.write(b"abcabc")
    distance = b.until(97)
    assert distance == 1
    distance = b.until(98)
    assert distance == 2
    distance = b.until(99)
    assert distance == 3
Beispiel #25
0
def test_can_find_bytes():
    b = ByteStream()
    b.write(b"abc")
    distance = b.until(97)
    assert distance == 1
    distance = b.until(98)
    assert distance == 2
    distance = b.until(99)
    assert distance == 3
Beispiel #26
0
    def sendRelay(self, targetId, targetPort, data, fromOutbound):
        # Loopback
        if self.id == targetId:
            # Send it to the opposite connection.
            conn = self.getConnection(targetId, targetPort, not fromOutbound)
            if conn:
                conn.injectRelayRead(data)
            else:
                debug("sendRelay: Loopback endpoint not found.")
            return

        if self.nodeState != NS_REGISTERED:
            debug("sendRelay: Node not registered. State is %d"%self.nodeState)
            return

        out = ByteStream()
        out.writeByte(P_RELAY_PACKET)
        out.writeString(targetId)
        out.writeString(targetPort)
        out.writeString(data)
        self.send(out)
Beispiel #27
0
def test_can_write_one_then_read_as_two():
    b = ByteStream()
    b.write(b"hello, world")
    read = b.read(6)
    assert read.tobytes() == b"hello,"
    read = b.read(6)
    assert read.tobytes() == b" world"
Beispiel #28
0
    def send(self, data):
        if isinstance(data, ByteStream):
            data = data.toString()

        packet = ByteStream()
        packet.writeByte(P_DATA)
        packet.writeString(data)
        data = packet.toString()

        self._send(data)
        self.lastPacketSent = time.time()
Beispiel #29
0
    def mainLoop(self):
        self.connectToNodeServer()

        while True:
            now = time.time()

            if now - self.lastPacketReceived > NS_KEEPALIVE_TIMEOUT:
                debug("Timed out.")
                self._disconnected()
                continue

            r, w, e = select([self.sock], [self.sock], [self.sock], 0)
            if r or e:
                try:
                    d = self.sock.recv(2048)
                except socket.error as e:
                    d = None
                    if e.errno == 10053:
                        debug("Connection aborted by software, maybe firewall?")
                    else:
                        debug("recv() error: errno=%d"%e.errno)
                if not d:
                    self._disconnected()
                    continue
                self.sockPacker.read(d)
                self.lastPacketReceived = now

            packet = self.sockPacker.popPacket()
            if packet:
                packet = ByteStream(packet)
                self.gotDataFromNodeServer(packet)

            if w:
                if now - self.lastKeepAliveSent > NS_KEEPALIVE_INTERVAL:
                    self.lastKeepAliveSent = now
                    self.send('')

                self.sockQueue.processNext()

            # Process stale requested connections.
            with self.connectionsLock:
                for connection in self.connections:
                    if connection.state == CS_REQUESTED and now - connection.requestTime > 4:
                        debug("Connection request for %s:%s timed out."%(connection.targetId, connection.targetPort))
                        connection.state = CS_FAILED_TIMED_OUT
                        self.connections.remove(connection)

            time.sleep(0.001)

        self.sock.close()
Beispiel #30
0
    def sendRelay(self, targetId, targetPort, data, fromOutbound):
        # Loopback
        if self.id == targetId:
            # Send it to the opposite connection.
            conn = self.getConnection(targetId, targetPort, not fromOutbound)
            if conn:
                conn.injectRelayRead(data)
            else:
                debug("sendRelay: Loopback endpoint not found.")
            return

        if self.nodeState != NS_REGISTERED:
            debug("sendRelay: Node not registered. State is %d" % self.nodeState)
            return

        out = ByteStream()
        out.writeByte(P_RELAY_PACKET)
        out.writeString(targetId)
        out.writeString(targetPort)
        out.writeString(data)
        self.send(out)
Beispiel #31
0
    def send(self, data):
        if isinstance(data, ByteStream):
            data = data.toString()

        packet = ByteStream()
        packet.writeByte(P_DATA)
        packet.writeString(data)
        data = packet.toString()

        self._send(data)
        self.lastPacketSent = time.time()
Beispiel #32
0
    def run(self):
        while True:
            now = time.time()

            r, w, e = select([self.sock], [self.sock], [self.sock], 0)
            if r or e:
                try:
                    data = self.sock.recv(2048)
                except socket.error as e:
                    debug("%s: .recv() died! errno=%d"%(self.id, e.errno))
                    break
                if not data:
                    if self.id:
                        debug("%s: closed"%self.id)
                    else:
                        debug("lost unknown connection")
                    break
                self.sockPacker.read(data)
                self.lastPacketReceived = now

            packet = self.sockPacker.popPacket()
            if packet:
                packet = ByteStream(packet)
                try:
                    self.handlePacket(packet)
                except:
                    debug("handlePacket crashed.")
                    debug(traceback.format_exc())

            if now - self.lastPacketReceived > KEEPALIVE_TIMEOUT:
                debug("%s: timed out."%self.id)
                self.sock.close()
                break

            if w:
                if now - self.lastKeepAliveSent > KEEPALIVE_INTERVAL:
                    self.lastKeepAliveSent = now
                    self.send('')

                self.sockQueue.processNext()
            time.sleep(0.01)
        self.ns.nodeDied(self.id)
Beispiel #33
0
 def __init__(self, output_stream, number, name, access, lock, reclen=128):
     """ Initialise random-access file. """
     # all text-file operations on a RANDOM file (PRINT, WRITE, INPUT, ...)
     # actually work on the FIELD buffer; the file stream itself is not
     # touched until PUT or GET.
     self.reclen = reclen
     # replace with empty field if already exists
     self.field = state.io_state.fields[number]
     self.field.reset(self.reclen)
     devices.CRLFTextFileBase.__init__(self, ByteStream(self.field.buffer),
                                       b'D', b'R')
     self.operating_mode = b'I'
     # note that for random files, output_stream must be a seekable stream.
     self.output_stream = output_stream
     self.lock_type = lock
     self.access = access
     self.lock_list = set()
     self.number = number
     self.name = name
     # position at start of file
     self.recpos = 0
     self.output_stream.seek(0)
Beispiel #34
0
    def handlePacket(self, data):
        packet = data.readByte()
        if packet == P_REGISTER:
            self.id = self.ns.pushNode(self)

            out = ByteStream()
            out.writeByte(P_REGISTER)
            out.writeString(self.id)
            self.send(out)
        elif packet == P_CONNECT_REQUEST:
            # from source node
            targetId = data.readString()
            targetPort = data.readString()
            debug("%s: requesting connect to %s"%(self.id, targetId))
            self.ns.sendConnectRequest(self, targetId, targetPort)
        elif packet == P_CONNECT_RESPONSE:
            # from target nodef
            targetId = data.readString()
            targetPort = data.readString()
            accepted = data.readBoolean()
            debug("%s: response for %s=%s"%(self.id, targetId, repr(accepted)))
            if accepted:
                self.ns.sendConnectSuccess(self, targetId, targetPort)
            else:
                self.ns.sendConnectRejected(self, targetId, targetPort)
        elif packet == P_TUNNEL_INFO:
            targetId = data.readString()
            targetPort = data.readString()
            privIp = data.readString()
            privPort = data.readInt()
            pubIp = data.readString()
            pubPort = data.readInt()
            debug("%s: sending tunnel info to %s"%(self.id, targetId))
            self.ns.sendTunnelInfo(self, targetId, targetPort, privIp, privPort, pubIp, pubPort)
        elif packet == P_RELAY_PACKET:
            targetId = data.readString()
            targetPort = data.readString()
            data = data.readString()
            self.ns.sendRelayPacket(self, targetId, targetPort, data)
Beispiel #35
0
    def updateNotConnected(self):
        if self.state == CS_TUNNELING:
            debug("Tunneling")
            self.tunnelTicks += 1

            # 0.2 x 20 = 4s for tunnel establishment
            if self.tunnelTicks == 21:
                # Switch to relay for now :(
                debug("Fallback to relay.")
                self.state = CS_CONNECTED
                self.relay = True
                if not self.outbound:
                    self.pushToPort()
                return

            mySyn = ByteStream()
            mySyn.writeByte(P_TUNNEL_SYN)
            mySyn.writeString(self.node.id)
            mySyn.writeString(self.targetPort)
            mySyn = mySyn.toString()

            myAck = ByteStream()
            myAck.writeByte(P_TUNNEL_ACK)
            myAck.writeString(self.node.id)
            myAck.writeString(self.targetPort)
            myAck = myAck.toString()

            theirSyn = ByteStream()
            theirSyn.writeByte(P_TUNNEL_SYN)
            theirSyn.writeString(self.targetId)
            theirSyn.writeString(self.targetPort)
            theirSyn = theirSyn.toString()

            theirAck = ByteStream()
            theirAck.writeByte(P_TUNNEL_ACK)
            theirAck.writeString(self.targetId)
            theirAck.writeString(self.targetPort)
            theirAck = theirAck.toString()

            while True:
                r, w, e = select([self.sock], [self.sock], [], 0)
                if r:
                    try:
                        data, addr = self.sock.recvfrom(4096)
                    except socket.error as e:
                        if e.errno == 10054:
                            # UDP returns a ECONNRESET for IMCP failures, ignore them
                            data = None
                    if data == theirSyn and not self.tunnelGotSyn:
                        self.tunnelGotSyn = True
                        debug("Got syn for tunnel.")
                    elif data == theirAck and self.tunnelGotSyn:
                        self.state = CS_CONNECTED

                        # Lock in the address
                        self.addr = addr
                        self.sock.connect(addr)

                        if not self.outbound:
                            self.pushToPort()

                        debug("Got ack. Tunnel established.")
                        break
                else:
                    break

            packetToSend = mySyn
            if self.tunnelGotSyn:
                self.sock.sendto(myAck, self.tunnelPrivAddr)
                self.sock.sendto(myAck, self.tunnelPubAddr)
                debug("Sending ack...")
            self.sock.sendto(mySyn, self.tunnelPrivAddr)
            self.sock.sendto(mySyn, self.tunnelPubAddr)
            debug("Sending syn...")

        if self.state != CS_CONNECTED and time.time() - self.acceptTime > 5:
            debug("Connect timed out. current=%d, accept=%d"%(time.time(), self.acceptTime))
            self.state = CS_FAILED_TIMED_OUT
            self.threadStopped.set()
            self.node.connectionDied(self)
Beispiel #36
0
 def sendTunnelInfo(self, targetId, targetPort, privIp, privPort, pubIp, pubPort):
     """ Sends tunnel info to a node. """
     out = ByteStream()
     out.writeByte(P_TUNNEL_INFO)
     out.writeString(targetId)
     out.writeString(targetPort)
     out.writeString(privIp)
     out.writeInt(privPort)
     out.writeString(pubIp)
     out.writeInt(pubPort)
     self.send(out)
Beispiel #37
0
    def run(self):
        self.acceptTime = time.time()

        if self.state != CS_CONNECTED:
            if not self.loopback:
                # Get tunnel info
                privIp = socket.gethostbyname(socket.gethostname())
                while True:
                    (privPort, pubIp, pubPort) = self.node.reflectAddress()

                    self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                    try:
                        self.sock.bind(("", privPort))
                    except:
                        debug("Fuzion: Port %d taken, selecting new port." % (privPort))
                        continue
                    break

                debug("Bound at", privPort)

                self.node.sendTunnelInfo(self.targetId, self.targetPort, privIp, privPort, pubIp, pubPort)
            else:
                self.state = CS_CONNECTED
                if not self.outbound:
                    self.pushToPort()

        while not self.threadStopped.isSet():
            now = time.time()

            if self.state != CS_CONNECTED:
                self.updateNotConnected()
                time.sleep(0.2)
                continue

            if self.relay:
                r = len(self.relayedRead) > 0
                w = 1
                e = 0
            else:
                r, w, e = select([self.sock], [self.sock], [], 0)
            if r:
                try:
                    data = ByteStream(self._recv())
                except socket.error as e:
                    if e.errno == 10054:
                        # UDP returns a ECONNRESET for IMCP failures, ignore them
                        pass
                    else:
                        debug("Connection errno=%d" % e.errno)
                else:
                    if data:
                        packetType = data.readByte()
                        if packetType == P_DATA:
                            self.pendingRecv.append(data.readString())
                        elif packetType == P_CLOSE:
                            self.closeInternal(ERR_CLOSED_BY_REMOTE)
                            break
                        elif packetType == P_KEEP_ALIVE:
                            pass
                        self.lastPacketReceived = now

                    if not data and data is not None:
                        debug("Empty, but not None packet?")

            if now - self.lastPacketSent > 5:
                packet = ByteStream()
                packet.writeByte(P_KEEP_ALIVE)
                self._send(packet.toString())

                self.lastPacketSent = now

            if self.lastPacketReceived > 0 and now - self.lastPacketReceived > 20:
                debug(
                    "Timeout, now=%d, lastPacket=%d, diff=%d"
                    % (now, self.lastPacketReceived, now - self.lastPacketReceived)
                )
                self.closeInternal(ERR_TIMED_OUT)
                break

            time.sleep(0.01)
Beispiel #38
0
    def thread():
        global currentKey, raidServer, raidClient

        net.node.waitForNS()

        # Connect to server...
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        try:
            sock.connect(PARSER_SERVER_ADDR)
        except:
            prnt("Failed to connect:")
            prnt(traceback.format_exc())
            wx.CallAfter(failureFunc, "connect_failed")
            return

        # Write data
        stream = ByteStream()
        stream.writeByte(pkt.JOIN_RAID)
        stream.writeByte(VERSION_INT)
        stream.writeString(key)
        stream.writeString(net.node.getId())
        sock.send(stream.toString())

        # Read data
        data = sock.recv(1024)
        stream = ByteStream(data)

        # Process data
        success = stream.readBoolean()
        if success:
            currentKey = key
            isHost = stream.readBoolean()
            serverNode = net.node.getId()
            if isHost:
                prnt("Raid: Joined raid, became host")
                raidServer = RaidServer(sock)
                raidServer.start()
            else:
                prnt("Raid: Joined raid, didn't become host")
                serverNode = stream.readString()
                sock.close()
            raidClient = RaidClient(serverNode, failureFunc, successFunc)
            raidClient.start()
        else:
            reason = stream.readString()
            wx.CallAfter(failureFunc, reason)
            sock.close()
Beispiel #39
0
    def run(self):
        self.acceptTime = time.time()

        if self.state != CS_CONNECTED:
            if not self.loopback:
                # Get tunnel info
                privIp = socket.gethostbyname(socket.gethostname())
                while True:
                    (privPort, pubIp, pubPort) = self.node.reflectAddress()

                    self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                    try:
                        self.sock.bind(('', privPort))
                    except:
                        debug("Fuzion: Port %d taken, selecting new port."%(privPort))
                        continue
                    break

                debug("Bound at", privPort)

                self.node.sendTunnelInfo(self.targetId, self.targetPort, privIp, privPort, pubIp, pubPort)
            else:
                self.state = CS_CONNECTED
                if not self.outbound:
                    self.pushToPort()

        while not self.threadStopped.isSet():
            now = time.time()

            if self.state != CS_CONNECTED:
                self.updateNotConnected()
                time.sleep(0.2)
                continue

            if self.relay:
                r = len(self.relayedRead) > 0
                w = 1
                e = 0
            else:
                r, w, e = select([self.sock], [self.sock], [], 0)
            if r:
                try:
                    data = ByteStream(self._recv())
                except socket.error as e:
                    if e.errno == 10054:
                        # UDP returns a ECONNRESET for IMCP failures, ignore them
                        pass
                    else:
                        debug("Connection errno=%d"%e.errno)
                else:
                    if data:
                        packetType = data.readByte()
                        if packetType == P_DATA:
                            self.pendingRecv.append(data.readString())
                        elif packetType == P_CLOSE:
                            self.closeInternal(ERR_CLOSED_BY_REMOTE)
                            break
                        elif packetType == P_KEEP_ALIVE:
                            pass
                        self.lastPacketReceived = now

                    if not data and data is not None:
                        debug("Empty, but not None packet?")

            if now - self.lastPacketSent > 5:
                packet = ByteStream()
                packet.writeByte(P_KEEP_ALIVE)
                self._send(packet.toString())

                self.lastPacketSent = now

            if self.lastPacketReceived > 0 and now - self.lastPacketReceived > 20:
                debug("Timeout, now=%d, lastPacket=%d, diff=%d"%(now, self.lastPacketReceived, now - self.lastPacketReceived))
                self.closeInternal(ERR_TIMED_OUT)
                break

            time.sleep(0.01)
Beispiel #40
0
 def sendTunnelInfo(self, targetId, targetPort, privIp, privPort, pubIp, pubPort):
     out = ByteStream()
     out.writeByte(P_TUNNEL_INFO)
     out.writeString(targetId)
     out.writeString(targetPort)
     out.writeString(privIp)
     out.writeInt(privPort)
     out.writeString(pubIp)
     out.writeInt(pubPort)
     self.send(out)
Beispiel #41
0
def getNewServerNode():
    global currentKey, raidServer

    # Connect to server...
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.connect(PARSER_SERVER_ADDR)
    except:
        prnt("Failed to connect:")
        prnt(traceback.format_exc())
        return

    # Write data
    stream = ByteStream()
    stream.writeByte(pkt.JOIN_RAID)
    stream.writeByte(VERSION_INT)
    stream.writeString(currentKey)
    stream.writeString(net.node.getId())
    sock.send(stream.toString())

    # Read data
    data = sock.recv(1024)
    stream = ByteStream(data)

    # Process data
    success = stream.readBoolean()
    if success:
        isHost = stream.readBoolean()
        serverNode = net.node.getId()
        if isHost:
            prnt("Raid: Became host")
            raidServer = RaidServer(sock)
            raidServer.start()
        else:
            prnt("Raid: Didn't become host")
            serverNode = stream.readString()
            sock.close()
        return serverNode
    return None
Beispiel #42
0
    def updateNotConnected(self):
        if self.state == CS_TUNNELING:
            debug("Tunneling")
            self.tunnelTicks += 1

            # 0.2 x 20 = 4s for tunnel establishment
            if self.tunnelTicks == 21:
                # Switch to relay for now :(
                debug("Fallback to relay.")
                self.state = CS_CONNECTED
                self.relay = True
                if not self.outbound:
                    self.pushToPort()
                return

            mySyn = ByteStream()
            mySyn.writeByte(P_TUNNEL_SYN)
            mySyn.writeString(self.node.id)
            mySyn.writeString(self.targetPort)
            mySyn = mySyn.toString()

            myAck = ByteStream()
            myAck.writeByte(P_TUNNEL_ACK)
            myAck.writeString(self.node.id)
            myAck.writeString(self.targetPort)
            myAck = myAck.toString()

            theirSyn = ByteStream()
            theirSyn.writeByte(P_TUNNEL_SYN)
            theirSyn.writeString(self.targetId)
            theirSyn.writeString(self.targetPort)
            theirSyn = theirSyn.toString()

            theirAck = ByteStream()
            theirAck.writeByte(P_TUNNEL_ACK)
            theirAck.writeString(self.targetId)
            theirAck.writeString(self.targetPort)
            theirAck = theirAck.toString()

            while True:
                r, w, e = select([self.sock], [self.sock], [], 0)
                if r:
                    try:
                        data, addr = self.sock.recvfrom(4096)
                    except socket.error as e:
                        if e.errno == 10054:
                            # UDP returns a ECONNRESET for IMCP failures, ignore them
                            data = None
                    if data == theirSyn and not self.tunnelGotSyn:
                        self.tunnelGotSyn = True
                        debug("Got syn for tunnel.")
                    elif data == theirAck and self.tunnelGotSyn:
                        self.state = CS_CONNECTED

                        # Lock in the address
                        self.addr = addr
                        self.sock.connect(addr)

                        if not self.outbound:
                            self.pushToPort()

                        debug("Got ack. Tunnel established.")
                        break
                else:
                    break

            packetToSend = mySyn
            if self.tunnelGotSyn:
                self.sock.sendto(myAck, self.tunnelPrivAddr)
                self.sock.sendto(myAck, self.tunnelPubAddr)
                debug("Sending ack...")
            self.sock.sendto(mySyn, self.tunnelPrivAddr)
            self.sock.sendto(mySyn, self.tunnelPubAddr)
            debug("Sending syn...")

        if self.state != CS_CONNECTED and time.time() - self.acceptTime > 5:
            debug("Connect timed out. current=%d, accept=%d" % (time.time(), self.acceptTime))
            self.state = CS_FAILED_TIMED_OUT
            self.threadStopped.set()
            self.node.connectionDied(self)
Beispiel #43
0
    def gotDataFromNodeServer(self, b):
        p = b.readByte()
        if p == P_REGISTER:
            with self.stateLock:
                self.id = b.readString()
            debug("Registered with node server, id is", self.id)
            self.updateNodeState(NS_REGISTERED)
        elif p == P_CONNECT_REQUEST:
            targetId = b.readString()
            targetPort = b.readString()
            port = self.getPort(targetPort)
            if port == None:
                debug("Rejecting unsilicited connection request from %s at port %s"%(targetId, targetPort))

                out = ByteStream()
                out.writeByte(P_CONNECT_RESPONSE)
                out.writeString(targetId)
                out.writeString(targetPort)
                out.writeBoolean(False)
                self.send(out)
            else:
                debug("Connection request from %s at port %s"%(targetId, targetPort))

                out = ByteStream()
                out.writeByte(P_CONNECT_RESPONSE)
                out.writeString(targetId)
                out.writeString(targetPort)
                out.writeBoolean(True)
                self.send(out)

                conn = NodeConnection(self, targetId, targetPort, False)
                conn.state = CS_ACCEPTED
                conn.start()
                self.connections.append(conn)
        elif p == P_CONNECT_RESPONSE:
            targetId = b.readString()
            targetPort = b.readString()
            errorCode = b.readByte()
            state = CS_ACCEPTED
            if errorCode == ERR_NO_NODE:
                state = CS_FAILED_NO_NODE
            elif errorCode == ERR_REJECTED:
                state = CS_FAILED_REJECTED

            self.updateConnectionState(targetId, targetPort, state, True)
            if state == CS_ACCEPTED:
                self.startConnection(targetId, targetPort, True)
            else:
                self.removeConnection(targetId, targetPort, True)
        elif p == P_TUNNEL_INFO:
            targetId = b.readString()
            targetPort = b.readString()
            privIp = b.readString()
            privPort = b.readInt()
            pubIp = b.readString()
            pubPort = b.readInt()

            conn = self.getConnection(targetId, targetPort)
            if conn != None:
                conn.gotTunnelInfo(privIp, privPort, pubIp, pubPort)
            else:
                debug("Got connection info for non existant connection to %s:%s"%(targetId, targetPort))
        elif p == P_RELAY_PACKET:
            targetId = b.readString()
            targetPort = b.readString()
            data = b.readString()

            conn = self.getConnection(targetId, targetPort)
            if conn:
                conn.injectRelayRead(data)
Beispiel #44
0
    def gotDataFromNodeServer(self, b):
        p = b.readByte()
        if p == P_REGISTER:
            with self.stateLock:
                self.id = b.readString()
            debug("Registered with node server, id is", self.id)
            self.updateNodeState(NS_REGISTERED)
        elif p == P_CONNECT_REQUEST:
            targetId = b.readString()
            targetPort = b.readString()
            port = self.getPort(targetPort)
            if port == None:
                debug("Rejecting unsilicited connection request from %s at port %s" % (targetId, targetPort))

                out = ByteStream()
                out.writeByte(P_CONNECT_RESPONSE)
                out.writeString(targetId)
                out.writeString(targetPort)
                out.writeBoolean(False)
                self.send(out)
            else:
                debug("Connection request from %s at port %s" % (targetId, targetPort))

                out = ByteStream()
                out.writeByte(P_CONNECT_RESPONSE)
                out.writeString(targetId)
                out.writeString(targetPort)
                out.writeBoolean(True)
                self.send(out)

                conn = NodeConnection(self, targetId, targetPort, False)
                conn.state = CS_ACCEPTED
                conn.start()
                self.connections.append(conn)
        elif p == P_CONNECT_RESPONSE:
            targetId = b.readString()
            targetPort = b.readString()
            errorCode = b.readByte()
            state = CS_ACCEPTED
            if errorCode == ERR_NO_NODE:
                state = CS_FAILED_NO_NODE
            elif errorCode == ERR_REJECTED:
                state = CS_FAILED_REJECTED

            self.updateConnectionState(targetId, targetPort, state, True)
            if state == CS_ACCEPTED:
                self.startConnection(targetId, targetPort, True)
            else:
                self.removeConnection(targetId, targetPort, True)
        elif p == P_TUNNEL_INFO:
            targetId = b.readString()
            targetPort = b.readString()
            privIp = b.readString()
            privPort = b.readInt()
            pubIp = b.readString()
            pubPort = b.readInt()

            conn = self.getConnection(targetId, targetPort)
            if conn != None:
                conn.gotTunnelInfo(privIp, privPort, pubIp, pubPort)
            else:
                debug("Got connection info for non existant connection to %s:%s" % (targetId, targetPort))
        elif p == P_RELAY_PACKET:
            targetId = b.readString()
            targetPort = b.readString()
            data = b.readString()

            conn = self.getConnection(targetId, targetPort)
            if conn:
                conn.injectRelayRead(data)