Пример #1
0
    def test_server_side_invalid_2(self):
        t = StringTransport()

        p = TestHandshakeProtocol()

        now = time.time()
        hs = CryptoHandshaker(p, now)

        p.init_handler(hs.gen_handler())

        p.makeConnection(t)
        self.assertEquals(t.value(), '')

        ver_pkt = struct.pack('B', self.protocol_version)
        invalid_hs_data = (('abcdefg' * int(self.handshake_length * 2 / 7)) +
                           'abcdefg'[:int(self.handshake_length * 2 % 7)])

        # version is ok
        err = p.dataReceived(ver_pkt)
        self.assertIdentical(err, None)
        # ... but the rest is just (the right amount of) rubbish
        err = p.dataReceived(invalid_hs_data)

        self.assertIsInstance(err, failure.Failure)
        self.assertIsInstance(err.value, HandshakeFailedError)
        self.assertFalse(t.disconnecting, 'should not be disconnecting')
        self.assertEquals(p.handshake_status, 'fail')
Пример #2
0
    def test_server_side_invalid_2(self):
        t = StringTransport()

        p = TestHandshakeProtocol()

        now = time.time()
        hs = Handshaker(p, now)

        p.init_handler(hs.gen_handler())

        p.makeConnection(t)
        self.assertEquals(t.value(), '')

        ver_pkt = struct.pack('B', self.protocol_version)
        invalid_hs_data = (('abcdefg' * int(self.handshake_length * 2 / 7)) +
                           'abcdefg'[:int(self.handshake_length * 2 % 7)])

        # version is ok
        err = p.dataReceived(ver_pkt)
        self.assertIdentical(err, None)
        # ... but the rest is just (the right amount of) rubbish
        err = p.dataReceived(invalid_hs_data)

        self.assertIsInstance(err, failure.Failure)
        self.assertIsInstance(err.value, HandshakeFailedError)
        self.assertFalse(t.disconnecting, 'should not be disconnecting')
        self.assertEquals(p.handshake_status, 'fail')
Пример #3
0
    def test_many_headers(self):
        # OK, this test is a bit brittle, as we assume the following
        # properties of the encoder/muxer:
        # * it will allocate new chunk stream ids as long as we
        #   provide it with unseen combinations of type and message
        #   stream id
        # * the allocated ids will be consecutive numbers
        # * given the exactly same args to sendMessage the second call
        #   will produce a bitstream of a message with completely
        #   compressed header
        #
        # At the moment that seems the only reasonable way to force
        # muxer to use higher chunk stream ids, with different levels
        # of header compression, using only the public API...

        # for now, make sure we're using SimpleChunkProducer:
        class LocalTestMuxer(Muxer):
            chunk_producer_class = chunks.SimpleChunkProducer

        # first, generate and mux a whole bunch of messages
        tm = StringTransport()
        mux = LocalTestMuxer(tm)

        for i in range(256 + 64 + 1):
            mux.sendMessage(0, chunks.MSG_DATA, i, VecBuf(['']))
            mux.sendMessage(0, chunks.MSG_DATA, i, VecBuf(['']))

        # ... now demux the resulting binary data
        td = StringTransport()
        p = TestDemuxerProtocol()

        dmx = MessagePassingDemuxer(p)

        p.init_handler(dmx.gen_handler())

        p.makeConnection(td)

        p.dataReceived(tm.value())

        demuxed = p.pop_messages()

        # ... and check it maches the result we expect based on the
        # above assumptions
        first_csid = demuxed[0][0].cs_id
        for i in range(256 + 64 + 1):
            h, body = demuxed[2 * i]
            self.assertEquals((h.cs_id, h.real_time, h.real_size, h.real_type,
                               h.real_ms_id),
                              (i + first_csid, 0, 0, 18, i))
            self.assertEquals((h.cs_id, h.time, h.size, h.type, h.ms_id),
                              (i + first_csid, 0, 0, 18, i))
            self.assertEquals(len(body), 0)

            h, body = demuxed[2 * i + 1]
            self.assertEquals((h.cs_id, h.real_time, h.real_size, h.real_type,
                               h.real_ms_id),
                              (i + first_csid, None, None, None, None))
            self.assertEquals((h.cs_id, h.time, h.size, h.type, h.ms_id),
                              (i + first_csid, 0, 0, 18, i))
            self.assertEquals(len(body), 0)
Пример #4
0
    def test_combined(self):

        d_in = {}
        d_out = {}

        type_reverse = { 1: chunks.PROTO_SET_CHUNK_SIZE,
                         4: chunks.PROTO_USER_CONTROL,
                         5: chunks.PROTO_WINDOW_SIZE,
                         6: chunks.PROTO_SET_BANDWIDTH,
                         8: chunks.MSG_AUDIO,
                         9: chunks.MSG_VIDEO,
                         20: chunks.MSG_COMMAND }

        # for now, make sure we're using SimpleChunkProducer:
        class LocalTestMuxer(Muxer):
            chunk_producer_class = chunks.SimpleChunkProducer

        # mux messages first
        tm = StringTransport()
        mux = LocalTestMuxer(tm)

        for msg in messages:
            if not msg:
                continue
            head, body = msg
            msg_type = type_reverse[head[4]]
            mux.sendMessage(head[1], msg_type, head[5], VecBuf([body]))
            if msg_type == chunks.PROTO_SET_CHUNK_SIZE:
                mux.set_chunk_size(int(body.encode('hex'), 16))
            d_in.setdefault(head[4], []).append((head[1], head[4], head[5],
                                                 body))

        # ... now try to demux the resulting binary data
        td = StringTransport()
        p = TestDemuxerProtocol()

        dmx = MessagePassingDemuxer(p)

        p.init_handler(dmx.gen_handler())

        p.makeConnection(td)

        p.dataReceived(tm.value())

        demuxed = p.pop_messages()

        # we can't rely on the received messages to be in the exact
        # same order as the sent ones...

        for head, body in demuxed:
            d_out.setdefault(head.type, []).append((head.abs_time,
                                                    head.type,
                                                    head.ms_id,
                                                    body.read(len(body))))

        self.assertEquals(d_in, d_out)
Пример #5
0
    def test_server_side_ok_plus(self):
        # similar as with test_complete_exchange_plus() - feeding some
        # additional data immediately following handshake data
        t = StringTransport()

        p = TestHandshakeProtocol()

        now = time.time()
        hs = Handshaker(p, now)

        p.init_handler(hs.gen_handler())

        p.makeConnection(t)
        # server shouldn't respond before spoken to
        self.assertEquals(t.value(), '')

        ver_pkt = struct.pack('B', self.protocol_version)

        err = p.dataReceived(ver_pkt)

        self.assertIdentical(err, None)

        # server may wait until it receives handshake packet before
        # responding, so not testing here

        hs_rand_data = '.' * (self.handshake_length - 8)
        timestamp = 42
        hs_pkt = struct.pack('>LL', timestamp, 0) + hs_rand_data

        err = p.dataReceived(hs_pkt)

        self.assertIdentical(err, None)
        # ... and here the server might send all the packets already,
        # and our implementation should do so, so that's what we test
        self.assert_(
            len(t.value()) == 1 + self.handshake_length * 2,
            'Response too short (%d)' % len(t.value()))

        self.assertEquals(
            struct.unpack_from('B', t.value(), 0)[0], self.protocol_version)

        srv_hs_pkt = t.value()[1:1 + self.handshake_length]
        hs_pkt_echo = t.value()[1 + self.handshake_length:1 +
                                self.handshake_length * 2]

        self.assertEquals(
            struct.unpack_from('>L', hs_pkt_echo, 0)[0], timestamp)
        self.assertEquals(hs_pkt_echo[8:], hs_rand_data)

        # server response ok, let's finish the server side, and
        # pretend client starts sending more data

        err = p.dataReceived(srv_hs_pkt + '\x00')

        self.assertIdentical(err, None)
        self.assertFalse(t.disconnecting, 'disconnecting')
        self.assertEquals(p.handshake_status, 'ok')
Пример #6
0
    def test_client_side_ok(self):
        t = StringTransport()

        p = TestHandshakeProtocol()

        now = time.time()
        hs = Handshaker(p, now, is_client=True)

        # can't initiate client handler before making connection
        p.init_handler(hs.gen_handler(), do_init=False)

        p.makeConnection(t)
        # client side is the active one
        self.assertEquals(t.value(), '')
        # ... once initiated
        p.init_handler()

        # after that the handling is almost identical to the server side...
        ver_pkt = struct.pack('B', self.protocol_version)

        err = p.dataReceived(ver_pkt)

        self.assertIdentical(err, None)

        hs_rand_data = '.' * (self.handshake_length - 8)
        timestamp = 42
        hs_pkt = struct.pack('>LL', timestamp, 0) + hs_rand_data

        err = p.dataReceived(hs_pkt)

        self.assertIdentical(err, None)
        self.assert_(
            len(t.value()) == 1 + self.handshake_length * 2,
            'Response too short (%d)' % len(t.value()))

        self.assertEquals(
            struct.unpack_from('B', t.value(), 0)[0], self.protocol_version)

        cli_hs_pkt = t.value()[1:1 + self.handshake_length]
        hs_pkt_echo = t.value()[1 + self.handshake_length:1 +
                                self.handshake_length * 2]

        self.assertEquals(
            struct.unpack_from('>L', hs_pkt_echo, 0)[0], timestamp)
        self.assertEquals(hs_pkt_echo[8:], hs_rand_data)

        err = p.dataReceived(cli_hs_pkt)

        self.assertIdentical(err, None)
        self.assertFalse(t.disconnecting, 'disconnecting')
        self.assertEquals(p.handshake_status, 'ok')
Пример #7
0
    def test_server_side_ok_plus(self):
        # similar as with test_complete_exchange_plus() - feeding some
        # additional data immediately following handshake data
        t = StringTransport()

        p = TestHandshakeProtocol()

        now = time.time()
        hs = Handshaker(p, now)

        p.init_handler(hs.gen_handler())

        p.makeConnection(t)
        # server shouldn't respond before spoken to
        self.assertEquals(t.value(), '')

        ver_pkt = struct.pack('B', self.protocol_version)

        err = p.dataReceived(ver_pkt)

        self.assertIdentical(err, None)

        # server may wait until it receives handshake packet before
        # responding, so not testing here

        hs_rand_data = '.' * (self.handshake_length - 8)
        timestamp = 42
        hs_pkt = struct.pack('>LL', timestamp, 0) + hs_rand_data

        err = p.dataReceived(hs_pkt)

        self.assertIdentical(err, None)
        # ... and here the server might send all the packets already,
        # and our implementation should do so, so that's what we test
        self.assert_(len(t.value()) == 1 + self.handshake_length * 2,
                     'Response too short (%d)' % len(t.value()))

        self.assertEquals(struct.unpack_from('B', t.value(), 0)[0],
                          self.protocol_version)

        srv_hs_pkt = t.value()[1:1+self.handshake_length]
        hs_pkt_echo = t.value()[1+self.handshake_length:
                                    1+self.handshake_length*2]

        self.assertEquals(struct.unpack_from('>L', hs_pkt_echo, 0)[0],
                          timestamp)
        self.assertEquals(hs_pkt_echo[8:], hs_rand_data)

        # server response ok, let's finish the server side, and
        # pretend client starts sending more data

        err = p.dataReceived(srv_hs_pkt + '\x00')

        self.assertIdentical(err, None)
        self.assertFalse(t.disconnecting, 'disconnecting')
        self.assertEquals(p.handshake_status, 'ok')
Пример #8
0
    def test_server_side_invalid_1(self):
        t = StringTransport()

        p = TestHandshakeProtocol()

        now = time.time()
        hs = CryptoHandshaker(p, now)

        p.init_handler(hs.gen_handler())

        p.makeConnection(t)
        self.assertEquals(t.value(), '')

        # sending version different from the server's version
        ver_pkt = struct.pack('B', self.protocol_version + 1)

        err = p.dataReceived(ver_pkt)

        self.assertIsInstance(err, failure.Failure)
        self.assertIsInstance(err.value, HandshakeFailedError)
        self.assertFalse(t.disconnecting, 'should not be disconnecting')
        self.assertEquals(p.handshake_status, 'fail')
Пример #9
0
    def test_server_side_invalid_1(self):
        t = StringTransport()

        p = TestHandshakeProtocol()

        now = time.time()
        hs = Handshaker(p, now)

        p.init_handler(hs.gen_handler())

        p.makeConnection(t)
        self.assertEquals(t.value(), '')

        # sending version different from the server's version
        ver_pkt = struct.pack('B', self.protocol_version + 1)

        err = p.dataReceived(ver_pkt)

        self.assertIsInstance(err, failure.Failure)
        self.assertIsInstance(err.value, HandshakeFailedError)
        self.assertFalse(t.disconnecting, 'should not be disconnecting')
        self.assertEquals(p.handshake_status, 'fail')
Пример #10
0
    def test_client_side_ok(self):
        t = StringTransport()

        p = TestHandshakeProtocol()

        now = time.time()
        hs = Handshaker(p, now, is_client=True)

        # can't initiate client handler before making connection
        p.init_handler(hs.gen_handler(), do_init=False)

        p.makeConnection(t)
        # client side is the active one
        self.assertEquals(t.value(), '')
        # ... once initiated
        p.init_handler()


        # after that the handling is almost identical to the server side...
        ver_pkt = struct.pack('B', self.protocol_version)

        err = p.dataReceived(ver_pkt)

        self.assertIdentical(err, None)

        hs_rand_data = '.' * (self.handshake_length - 8)
        timestamp = 42
        hs_pkt = struct.pack('>LL', timestamp, 0) + hs_rand_data

        err = p.dataReceived(hs_pkt)

        self.assertIdentical(err, None)
        self.assert_(len(t.value()) == 1 + self.handshake_length * 2,
                     'Response too short (%d)' % len(t.value()))

        self.assertEquals(struct.unpack_from('B', t.value(), 0)[0],
                          self.protocol_version)

        cli_hs_pkt = t.value()[1:1+self.handshake_length]
        hs_pkt_echo = t.value()[1+self.handshake_length:
                                    1+self.handshake_length*2]

        self.assertEquals(struct.unpack_from('>L', hs_pkt_echo, 0)[0],
                          timestamp)
        self.assertEquals(hs_pkt_echo[8:], hs_rand_data)

        err = p.dataReceived(cli_hs_pkt)

        self.assertIdentical(err, None)
        self.assertFalse(t.disconnecting, 'disconnecting')
        self.assertEquals(p.handshake_status, 'ok')
Пример #11
0
    def test_data_per_chunk(self):
        t = StringTransport()
        p = TestDemuxerProtocol()

        dmx = MessagePassingDemuxer(p)

        p.init_handler(dmx.gen_handler())

        p.makeConnection(t)

        for i, (d, m) in enumerate(zip(data, messages)):
            p.dataReceived(d)
            rcvd = p.pop_messages()
            if m:
                fail_msg = '(not matching index: %d)' % i
                self.assertEquals(len(rcvd), 1, fail_msg)
                self.assertMatching(rcvd[0], m, fail_msg)
Пример #12
0
    def _test_data_chopped(self, sizes):
        t = StringTransport()
        p = TestDemuxerProtocol()

        dmx = MessagePassingDemuxer(p)

        p.init_handler(dmx.gen_handler())

        p.makeConnection(t)

        # filter out Nones
        expected = [m for m in messages if m]

        for d in chopped(''.join(data), sizes):
            p.dataReceived(d)

        received = p.pop_messages()

        self.assertEquals(len(received), len(expected))
        for i, (r, e) in enumerate(zip(received, expected)):
            self.assertMatching(r, e, '(not matching index: %d)' % i)
Пример #13
0
    def test_complete_exchange_plus(self):
        # almost exactly the same test as above except writing some
        # additional (garbage) data immediately (as in the same
        # "socket.read()") after the handshake data
        tcli = StringTransport()
        tsrv = StringTransport()

        p_cli = TestHandshakeProtocol()
        p_srv = TestHandshakeProtocol()

        now = time.time()
        hs_cli = Handshaker(p_cli, now - 0.001, is_client=True)
        hs_srv = Handshaker(p_srv, now - 0.042)


        p_srv.init_handler(hs_srv.gen_handler())
        p_cli.init_handler(hs_cli.gen_handler(), do_init=False)

        p_srv.makeConnection(tsrv)
        self.assertEquals(tsrv.value(), '')

        p_cli.makeConnection(tcli)
        self.assertEquals(tcli.value(), '')

        p_cli.init_handler()

        # self.assertEquals(len(tcli.value()), 1 + 1536)
        err = p_srv.dataReceived(tcli.value())
        tcli.clear()

        # self.assertEquals(len(tsrv.value()), 1 + 1536 + 1536)
        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, None)

        err = p_cli.dataReceived(tsrv.value() + '\x00')
        tsrv.clear()

        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, 'ok')
        self.assertEquals(p_srv.handshake_status, None)

        err = p_srv.dataReceived(tcli.value() + '\x00')
        tcli.clear()

        self.assertIdentical(err, None)
        self.assertFalse(tsrv.disconnecting, 'disconnecting')
        self.assertFalse(tcli.disconnecting, 'disconnecting')

        self.assertEquals(p_srv.handshake_status, 'ok')
Пример #14
0
    def test_complete_exchange(self):
        tcli = StringTransport()
        tsrv = StringTransport()

        p_cli = TestHandshakeProtocol()
        p_srv = TestHandshakeProtocol()

        now = time.time()
        hs_cli = Handshaker(p_cli, now - 0.001, is_client=True)
        hs_srv = Handshaker(p_srv, now - 0.042)


        p_srv.init_handler(hs_srv.gen_handler())
        p_cli.init_handler(hs_cli.gen_handler(), do_init=False)

        p_srv.makeConnection(tsrv)
        self.assertEquals(tsrv.value(), '')

        p_cli.makeConnection(tcli)
        self.assertEquals(tcli.value(), '')

        p_cli.init_handler()

        # self.assertEquals(len(tcli.value()), 1 + 1536)
        err = p_srv.dataReceived(tcli.value())
        tcli.clear()

        # self.assertEquals(len(tsrv.value()), 1 + 1536 + 1536)
        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, None)

        err = p_cli.dataReceived(tsrv.value())
        tsrv.clear()

        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, 'ok')
        self.assertEquals(p_srv.handshake_status, None)

        err = p_srv.dataReceived(tcli.value())
        tcli.clear()

        self.assertIdentical(err, None)
        self.assertFalse(tsrv.disconnecting, 'disconnecting')
        self.assertFalse(tcli.disconnecting, 'disconnecting')

        self.assertEquals(p_srv.handshake_status, 'ok')
Пример #15
0
    def test_complete_exchange(self):
        tcli = StringTransport()
        tsrv = StringTransport()

        p_cli = TestHandshakeProtocol()
        p_srv = TestHandshakeProtocol()

        now = time.time()
        hs_cli = Handshaker(p_cli, now - 0.001, is_client=True)
        hs_srv = Handshaker(p_srv, now - 0.042)

        p_srv.init_handler(hs_srv.gen_handler())
        p_cli.init_handler(hs_cli.gen_handler(), do_init=False)

        p_srv.makeConnection(tsrv)
        self.assertEquals(tsrv.value(), '')

        p_cli.makeConnection(tcli)
        self.assertEquals(tcli.value(), '')

        p_cli.init_handler()

        # self.assertEquals(len(tcli.value()), 1 + 1536)
        err = p_srv.dataReceived(tcli.value())
        tcli.clear()

        # self.assertEquals(len(tsrv.value()), 1 + 1536 + 1536)
        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, None)

        err = p_cli.dataReceived(tsrv.value())
        tsrv.clear()

        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, 'ok')
        self.assertEquals(p_srv.handshake_status, None)

        err = p_srv.dataReceived(tcli.value())
        tcli.clear()

        self.assertIdentical(err, None)
        self.assertFalse(tsrv.disconnecting, 'disconnecting')
        self.assertFalse(tcli.disconnecting, 'disconnecting')

        self.assertEquals(p_srv.handshake_status, 'ok')
Пример #16
0
    def test_complete_exchange_plus(self):
        # almost exactly the same test as above except writing some
        # additional (garbage) data immediately (as in the same
        # "socket.read()") after the handshake data
        tcli = StringTransport()
        tsrv = StringTransport()

        p_cli = TestHandshakeProtocol()
        p_srv = TestHandshakeProtocol()

        now = time.time()
        hs_cli = Handshaker(p_cli, now - 0.001, is_client=True)
        hs_srv = Handshaker(p_srv, now - 0.042)

        p_srv.init_handler(hs_srv.gen_handler())
        p_cli.init_handler(hs_cli.gen_handler(), do_init=False)

        p_srv.makeConnection(tsrv)
        self.assertEquals(tsrv.value(), '')

        p_cli.makeConnection(tcli)
        self.assertEquals(tcli.value(), '')

        p_cli.init_handler()

        # self.assertEquals(len(tcli.value()), 1 + 1536)
        err = p_srv.dataReceived(tcli.value())
        tcli.clear()

        # self.assertEquals(len(tsrv.value()), 1 + 1536 + 1536)
        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, None)

        err = p_cli.dataReceived(tsrv.value() + '\x00')
        tsrv.clear()

        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, 'ok')
        self.assertEquals(p_srv.handshake_status, None)

        err = p_srv.dataReceived(tcli.value() + '\x00')
        tcli.clear()

        self.assertIdentical(err, None)
        self.assertFalse(tsrv.disconnecting, 'disconnecting')
        self.assertFalse(tcli.disconnecting, 'disconnecting')

        self.assertEquals(p_srv.handshake_status, 'ok')
Пример #17
0
    def _test_complete_exchange(self, client_handshaker_class,
                                client_failure=False, server_failure=False):
        tcli = StringTransport()
        tsrv = StringTransport()

        p_cli = TestHandshakeProtocol()
        p_srv = TestHandshakeProtocol()

        now = time.time()
        hs_cli = client_handshaker_class(p_cli, now - 0.001, is_client=True)
        hs_srv = CryptoHandshaker(p_srv, now - 0.042)


        p_srv.init_handler(hs_srv.gen_handler())
        p_cli.init_handler(hs_cli.gen_handler(), do_init=False)

        p_srv.makeConnection(tsrv)
        self.assertEquals(tsrv.value(), '')

        p_cli.makeConnection(tcli)
        self.assertEquals(tcli.value(), '')

        p_cli.init_handler()

        # self.assertEquals(len(tcli.value()), 1 + 1536)
        err = p_srv.dataReceived(tcli.value())
        tcli.clear()

        # self.assertEquals(len(tsrv.value()), 1 + 1536 + 1536)
        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, None)

        err = p_cli.dataReceived(tsrv.value() + '\x00')
        tsrv.clear()

        if client_failure:
            self.assertIsInstance(err, failure.Failure)
            self.assertIsInstance(err.value, HandshakeFailedError)
            self.assertFalse(tcli.disconnecting, 'should not be disconnecting')
            self.assertEquals(p_cli.handshake_status, 'fail')
            self.assertEquals(p_srv.handshake_status, None)
        else:
            self.assertIdentical(err, None)
            self.assertFalse(tcli.disconnecting, 'disconnecting')
            self.assertEquals(p_cli.handshake_status, 'ok')
            self.assertEquals(p_srv.handshake_status, None)


        err = p_srv.dataReceived(tcli.value() + '\x00')
        tcli.clear()

        if server_failure:
            self.assertIsInstance(err, failure.Failure)
            self.assertIsInstance(err.value, HandshakeFailedError)
            self.assertFalse(tsrv.disconnecting, 'should not be disconnecting')
            self.assertEquals(p_srv.handshake_status, 'fail')
        else:
            self.assertIdentical(err, None)
            self.assertFalse(tsrv.disconnecting, 'disconnecting')
            self.assertEquals(p_srv.handshake_status, 'ok')
Пример #18
0
    def _test_complete_exchange(self,
                                client_handshaker_class,
                                client_failure=False,
                                server_failure=False):
        tcli = StringTransport()
        tsrv = StringTransport()

        p_cli = TestHandshakeProtocol()
        p_srv = TestHandshakeProtocol()

        now = time.time()
        hs_cli = client_handshaker_class(p_cli, now - 0.001, is_client=True)
        hs_srv = CryptoHandshaker(p_srv, now - 0.042)

        p_srv.init_handler(hs_srv.gen_handler())
        p_cli.init_handler(hs_cli.gen_handler(), do_init=False)

        p_srv.makeConnection(tsrv)
        self.assertEquals(tsrv.value(), '')

        p_cli.makeConnection(tcli)
        self.assertEquals(tcli.value(), '')

        p_cli.init_handler()

        # self.assertEquals(len(tcli.value()), 1 + 1536)
        err = p_srv.dataReceived(tcli.value())
        tcli.clear()

        # self.assertEquals(len(tsrv.value()), 1 + 1536 + 1536)
        self.assertIdentical(err, None)
        self.assertEquals(p_cli.handshake_status, None)

        err = p_cli.dataReceived(tsrv.value() + '\x00')
        tsrv.clear()

        if client_failure:
            self.assertIsInstance(err, failure.Failure)
            self.assertIsInstance(err.value, HandshakeFailedError)
            self.assertFalse(tcli.disconnecting, 'should not be disconnecting')
            self.assertEquals(p_cli.handshake_status, 'fail')
            self.assertEquals(p_srv.handshake_status, None)
        else:
            self.assertIdentical(err, None)
            self.assertFalse(tcli.disconnecting, 'disconnecting')
            self.assertEquals(p_cli.handshake_status, 'ok')
            self.assertEquals(p_srv.handshake_status, None)

        err = p_srv.dataReceived(tcli.value() + '\x00')
        tcli.clear()

        if server_failure:
            self.assertIsInstance(err, failure.Failure)
            self.assertIsInstance(err.value, HandshakeFailedError)
            self.assertFalse(tsrv.disconnecting, 'should not be disconnecting')
            self.assertEquals(p_srv.handshake_status, 'fail')
        else:
            self.assertIdentical(err, None)
            self.assertFalse(tsrv.disconnecting, 'disconnecting')
            self.assertEquals(p_srv.handshake_status, 'ok')