Beispiel #1
0
 def test_cannot_pair_ipv4_ipv6(self):
     candidate_a = Candidate.from_sdp(
         '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0')
     candidate_b = Candidate.from_sdp(
         '6815297761 1 udp 659136 2a02:0db8:85a3:0000:0000:8a2e:0370:7334 12345'
         ' typ host generation 0')
     self.assertFalse(candidate_a.can_pair_with(candidate_b))
Beispiel #2
0
    def test_add_remote_candidate_mdns(self):
        """
        mDNS is not supported yet, ignore such candidates.
        """
        conn_a = ice.Connection(ice_controlling=True)

        conn_a.add_remote_candidate(
            Candidate(
                foundation="some-foundation",
                component=1,
                transport="udp",
                priority=1234,
                host="a64e1aa4-8c7e-4671-ab02-e6a3483b1cd9.local",
                port=1234,
                type="host",
            ))
        self.assertEqual(len(conn_a.remote_candidates), 0)
        self.assertEqual(conn_a._remote_candidates_end, False)

        conn_a.add_remote_candidate(
            Candidate(
                foundation="some-foundation",
                component=1,
                transport="udp",
                priority=1234,
                host="1.2.3.4",
                port=1234,
                type="host",
            ))
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a.remote_candidates[0].host, "1.2.3.4")
        self.assertEqual(conn_a._remote_candidates_end, False)
Beispiel #3
0
    def test_set_remote_candidates_mdns(self):
        conn_a = ice.Connection(ice_controlling=True)

        conn_a.remote_candidates = [
            Candidate(
                foundation='some-foundation',
                component=1,
                transport='udp',
                priority=1234,
                host='a64e1aa4-8c7e-4671-ab02-e6a3483b1cd9.local',
                port=1234,
                type='host',
            ),
            Candidate(
                foundation='some-foundation',
                component=1,
                transport='udp',
                priority=1234,
                host='1.2.3.4',
                port=1234,
                type='host',
            )
        ]
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a.remote_candidates[0].host, '1.2.3.4')
        self.assertEqual(conn_a._remote_candidates_end, True)
Beispiel #4
0
    def test_set_remote_candidates_mdns(self):
        conn_a = ice.Connection(ice_controlling=True)

        conn_a.remote_candidates = [
            Candidate(
                foundation="some-foundation",
                component=1,
                transport="udp",
                priority=1234,
                host="a64e1aa4-8c7e-4671-ab02-e6a3483b1cd9.local",
                port=1234,
                type="host",
            ),
            Candidate(
                foundation="some-foundation",
                component=1,
                transport="udp",
                priority=1234,
                host="1.2.3.4",
                port=1234,
                type="host",
            ),
        ]
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a.remote_candidates[0].host, "1.2.3.4")
        self.assertEqual(conn_a._remote_candidates_end, True)
Beispiel #5
0
 def test_cannot_pair_different_transports(self):
     candidate_a = Candidate.from_sdp(
         '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0')
     candidate_b = Candidate.from_sdp(
         '6815297761 1 tcp 659136 1.2.3.4 12345 typ host generation 0 tcptype active'
     )
     self.assertFalse(candidate_a.can_pair_with(candidate_b))
 def test_cannot_pair_different_components(self):
     candidate_a = Candidate.from_sdp(
         "6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0"
     )
     candidate_b = Candidate.from_sdp(
         "6815297761 2 udp 659136 1.2.3.4 12345 typ host generation 0"
     )
     self.assertFalse(candidate_a.can_pair_with(candidate_b))
 def test_can_pair_ipv4(self):
     candidate_a = Candidate.from_sdp(
         "6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0"
     )
     candidate_b = Candidate.from_sdp(
         "6815297761 1 udp 659136 1.2.3.4 12345 typ host generation 0"
     )
     self.assertTrue(candidate_a.can_pair_with(candidate_b))
 def test_can_pair_ipv6(self):
     candidate_a = Candidate.from_sdp(
         "6815297761 1 udp 659136 2a02:0db8:85a3:0000:0000:8a2e:0370:7334 31102"
         " typ host generation 0"
     )
     candidate_b = Candidate.from_sdp(
         "6815297761 1 udp 659136 2a02:0db8:85a3:0000:0000:8a2e:0370:7334 12345"
         " typ host generation 0"
     )
     self.assertTrue(candidate_a.can_pair_with(candidate_b))
Beispiel #9
0
    def test_response_with_invalid_address(self):
        connection = ice.Connection(ice_controlling=True)
        connection.remote_password = "******"
        connection.remote_username = "******"

        protocol = ProtocolMock()
        protocol.response_addr = ("3.4.5.6", 3456)
        protocol.response_message = "bad"

        pair = ice.CandidatePair(
            protocol,
            Candidate(
                foundation="some-foundation",
                component=1,
                transport="udp",
                priority=2345,
                host="2.3.4.5",
                port=2345,
                type="host",
            ),
        )
        self.assertEqual(
            repr(pair), "CandidatePair(('1.2.3.4', 1234) -> ('2.3.4.5', 2345))"
        )

        run(connection.check_start(pair))
        self.assertEqual(pair.state, ice.CandidatePair.State.FAILED)
Beispiel #10
0
    def test_add_remote_candidate(self):
        conn_a = ice.Connection(ice_controlling=True)

        remote_candidate = Candidate(foundation='some-foundation',
                                     component=1,
                                     transport='udp',
                                     priority=1234,
                                     host='1.2.3.4',
                                     port=1234,
                                     type='host')

        # add candidate
        conn_a.add_remote_candidate(remote_candidate)
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a._remote_candidates_end, False)

        # end-of-candidates
        conn_a.add_remote_candidate(None)
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a._remote_candidates_end, True)

        # try adding another candidate
        with self.assertRaises(ValueError) as cm:
            conn_a.add_remote_candidate(remote_candidate)
        self.assertEqual(
            str(cm.exception),
            'Cannot add remote candidate after end-of-candidates.')
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a._remote_candidates_end, True)
Beispiel #11
0
    def test_set_remote_candidates(self):
        conn_a = ice.Connection(ice_controlling=True)

        remote_candidates = [
            Candidate(foundation='some-foundation',
                      component=1,
                      transport='udp',
                      priority=1234,
                      host='1.2.3.4',
                      port=1234,
                      type='host')
        ]

        # set candidates
        conn_a.remote_candidates = remote_candidates
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a._remote_candidates_end, True)

        # try setting candidates again
        with self.assertRaises(ValueError) as cm:
            conn_a.remote_candidates = remote_candidates
        self.assertEqual(
            str(cm.exception),
            'Cannot set remote candidates after end-of-candidates.')
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a._remote_candidates_end, True)
Beispiel #12
0
 async def _handle_ice_candidates(self):
     """
     (*Coroutine*) Coroutine that handle the ICE candidates negotiation.
     """
     while self.readyState == PeerState.CONNECTING or self.readyState == PeerState.CONNECTED:
         signal = await self._get_signal()
         if 'type' in signal:
             if signal['type'] == 'status' and signal[
                     'status'] == 'unpaired':
                 if self.readyState == PeerState.CONNECTED:
                     logging.info('unpaired received, disconnecting...')
                     self.disconnection_event.set()
         elif 'candidate' in signal:
             logging.info('Got ice candidate:')
             candi = Candidate.from_sdp(signal['candidate']['candidate'])
             candidate = RTCIceCandidate(
                 component=candi.component,
                 foundation=candi.foundation,
                 ip=candi.host,
                 port=candi.port,
                 priority=candi.priority,
                 protocol=candi.transport,
                 relatedAddress=candi.related_address,
                 relatedPort=candi.related_port,
                 tcpType=candi.tcptype,
                 type=candi.type,
                 sdpMLineIndex=signal['candidate']['sdpMLineIndex'],
                 sdpMid=signal['candidate']['sdpMid'])
             logging.debug(candidate)
             self._pc.addIceCandidate(candidate)
         else:
             raise Exception('Received an unexpected signal: ', signal)
Beispiel #13
0
 def test_repr(self):
     candidate = Candidate.from_sdp(
         '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0')
     self.assertEqual(
         repr(candidate),
         'Candidate(6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0)'
     )
Beispiel #14
0
    async def test_add_remote_candidate_mdns_good(self):
        """
        Add an mDNS candidate which can be resolved.
        """
        hostname = mdns.create_mdns_hostname()
        publisher = await mdns.create_mdns_protocol()
        await publisher.publish(hostname, "1.2.3.4")

        conn_a = ice.Connection(ice_controlling=True)

        await conn_a.add_remote_candidate(
            Candidate(
                foundation="some-foundation",
                component=1,
                transport="udp",
                priority=1234,
                host=hostname,
                port=1234,
                type="host",
            ))
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a.remote_candidates[0].host, "1.2.3.4")
        self.assertEqual(conn_a._remote_candidates_end, False)

        # close
        await conn_a.close()
        await publisher.close()
Beispiel #15
0
    async def test_add_remote_candidate(self):
        conn_a = ice.Connection(ice_controlling=True)

        remote_candidate = Candidate(
            foundation="some-foundation",
            component=1,
            transport="udp",
            priority=1234,
            host="1.2.3.4",
            port=1234,
            type="host",
        )

        # add candidate
        await conn_a.add_remote_candidate(remote_candidate)
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a.remote_candidates[0].host, "1.2.3.4")
        self.assertEqual(conn_a._remote_candidates_end, False)

        # end-of-candidates
        await conn_a.add_remote_candidate(None)
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a._remote_candidates_end, True)

        # try adding another candidate
        with self.assertRaises(ValueError) as cm:
            await conn_a.add_remote_candidate(remote_candidate)
        self.assertEqual(
            str(cm.exception),
            "Cannot add remote candidate after end-of-candidates.")
        self.assertEqual(len(conn_a.remote_candidates), 1)
        self.assertEqual(conn_a._remote_candidates_end, True)
Beispiel #16
0
def candidate_to_aioice(x):
    return Candidate(component=x.component,
                     foundation=x.foundation,
                     host=x.ip,
                     port=x.port,
                     priority=x.priority,
                     transport=x.protocol,
                     tcptype=x.tcpType,
                     type=x.type)
    async def add_candidate_to_pc(self, pc_id, candidate=RTCIceCandidate):
        logger.info("add_candidate_to_pc {}".format(candidate))
        if candidate:
            this_candidate = candidate.get("candidate")
            if this_candidate:
                logger.info("---------- {}".format(candidate["candidate"]))
                candidate_inst = Candidate.from_sdp(candidate["candidate"])

                rTCIceCandidate = candidate_from_aioice(candidate_inst)
                rTCIceCandidate.sdp = candidate["sdpMid"]
                rTCIceCandidate.sdpMLineIndex = candidate["sdpMLineIndex"]
Beispiel #18
0
 def test_connect_no_remote_credentials(self):
     """
     If remote credentials have not been provided, connect fails.
     """
     conn = ice.Connection(ice_controlling=True)
     run(conn.gather_candidates())
     conn.remote_candidates = [Candidate.from_sdp(
         '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0')]
     with self.assertRaises(ConnectionError) as cm:
         run(conn.connect())
     self.assertEqual(str(cm.exception), 'Remote username or password is missing')
     run(conn.close())
Beispiel #19
0
 def test_connect_no_local_candidates(self):
     """
     If local candidates have not been gathered, connect fails.
     """
     conn = ice.Connection(ice_controlling=True)
     conn.remote_candidates = [Candidate.from_sdp(
         '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0')]
     conn.remote_username = '******'
     conn.remote_password = '******'
     with self.assertRaises(ConnectionError):
         run(conn.connect())
     run(conn.close())
Beispiel #20
0
    def test_connect_timeout(self):
        # lower STUN retries
        stun.RETRY_MAX = 2

        conn = ice.Connection(ice_controlling=True)
        run(conn.gather_candidates())
        conn.remote_candidates = [Candidate.from_sdp(
            '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0')]
        conn.remote_username = '******'
        conn.remote_password = '******'
        with self.assertRaises(ConnectionError):
            run(conn.connect())
        run(conn.close())
Beispiel #21
0
def candidate_to_aioice(x: RTCIceCandidate) -> Candidate:
    return Candidate(
        component=x.component,
        foundation=x.foundation,
        host=x.ip,
        port=x.port,
        priority=x.priority,
        related_address=x.relatedAddress,
        related_port=x.relatedPort,
        transport=x.protocol,
        tcptype=x.tcpType,
        type=x.type,
    )
Beispiel #22
0
 def test_connect_no_gather(self):
     """
     If local candidates gathering was not performed, connect fails.
     """
     conn = ice.Connection(ice_controlling=True)
     conn.remote_candidates = [Candidate.from_sdp(
         '6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0')]
     conn.remote_username = '******'
     conn.remote_password = '******'
     with self.assertRaises(ConnectionError) as cm:
         run(conn.connect())
     self.assertEqual(str(cm.exception), 'Local candidates gathering was not performed')
     run(conn.close())
Beispiel #23
0
 async def test_connect_no_remote_credentials(self):
     """
     If remote credentials have not been provided, connect fails.
     """
     conn = ice.Connection(ice_controlling=True)
     await conn.gather_candidates()
     await conn.add_remote_candidate(
         Candidate.from_sdp(
             "6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0"))
     await conn.add_remote_candidate(None)
     with self.assertRaises(ConnectionError) as cm:
         await conn.connect()
     self.assertEqual(str(cm.exception),
                      "Remote username or password is missing")
     await conn.close()
Beispiel #24
0
    def test_from_sdp_no_generation(self):
        candidate = Candidate.from_sdp(
            '6815297761 1 udp 659136 1.2.3.4 31102 typ host')

        self.assertEqual(candidate.foundation, '6815297761')
        self.assertEqual(candidate.component, 1)
        self.assertEqual(candidate.transport, 'udp')
        self.assertEqual(candidate.priority, 659136)
        self.assertEqual(candidate.host, '1.2.3.4')
        self.assertEqual(candidate.port, 31102)
        self.assertEqual(candidate.type, 'host')
        self.assertEqual(candidate.generation, None)

        self.assertEqual(candidate.to_sdp(),
                         '6815297761 1 udp 659136 1.2.3.4 31102 typ host')
Beispiel #25
0
    def test_add_remote_candidate_unknown_type(self):
        conn_a = ice.Connection(ice_controlling=True)

        conn_a.add_remote_candidate(
            Candidate(
                foundation="some-foundation",
                component=1,
                transport="udp",
                priority=1234,
                host="1.2.3.4",
                port=1234,
                type="bogus",
            ))
        self.assertEqual(len(conn_a.remote_candidates), 0)
        self.assertEqual(conn_a._remote_candidates_end, False)
Beispiel #26
0
    def test_from_sdp_no_generation(self):
        candidate = Candidate.from_sdp("6815297761 1 udp 659136 1.2.3.4 31102 typ host")

        self.assertEqual(candidate.foundation, "6815297761")
        self.assertEqual(candidate.component, 1)
        self.assertEqual(candidate.transport, "udp")
        self.assertEqual(candidate.priority, 659136)
        self.assertEqual(candidate.host, "1.2.3.4")
        self.assertEqual(candidate.port, 31102)
        self.assertEqual(candidate.type, "host")
        self.assertEqual(candidate.generation, None)

        self.assertEqual(
            candidate.to_sdp(), "6815297761 1 udp 659136 1.2.3.4 31102 typ host"
        )
Beispiel #27
0
 async def test_connect_no_gather(self):
     """
     If local candidates gathering was not performed, connect fails.
     """
     conn = ice.Connection(ice_controlling=True)
     await conn.add_remote_candidate(
         Candidate.from_sdp(
             "6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0"))
     await conn.add_remote_candidate(None)
     conn.remote_username = "******"
     conn.remote_password = "******"
     with self.assertRaises(ConnectionError) as cm:
         await conn.connect()
     self.assertEqual(str(cm.exception),
                      "Local candidates gathering was not performed")
     await conn.close()
Beispiel #28
0
 def test_connect_no_local_candidates(self):
     """
     If local candidates gathering yielded no candidates, connect fails.
     """
     conn = ice.Connection(ice_controlling=True)
     conn._local_candidates_end = True
     conn.add_remote_candidate(
         Candidate.from_sdp(
             "6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0"))
     conn.add_remote_candidate(None)
     conn.remote_username = "******"
     conn.remote_password = "******"
     with self.assertRaises(ConnectionError) as cm:
         run(conn.connect())
     self.assertEqual(str(cm.exception), "ICE negotiation failed")
     run(conn.close())
Beispiel #29
0
    def test_connect_timeout(self):
        # lower STUN retries
        stun.RETRY_MAX = 1

        conn = ice.Connection(ice_controlling=True)
        run(conn.gather_candidates())
        conn.add_remote_candidate(
            Candidate.from_sdp(
                "6815297761 1 udp 659136 1.2.3.4 31102 typ host generation 0"))
        conn.add_remote_candidate(None)
        conn.remote_username = "******"
        conn.remote_password = "******"
        with self.assertRaises(ConnectionError) as cm:
            run(conn.connect())
        self.assertEqual(str(cm.exception), "ICE negotiation failed")
        run(conn.close())
Beispiel #30
0
class ProtocolMock:
    local_candidate = Candidate(foundation='some-foundation',
                                component=1,
                                transport='udp',
                                priority=1234,
                                host='1.2.3.4',
                                port=1234,
                                type='host')

    sent_message = None

    async def request(self, message, addr, integrity_key=None):
        return (self.response_message, self.response_addr)

    def send_stun(self, message, addr):
        self.sent_message = message