- // FIXME: make sure _peer gets deleted
- // TODO: socket ownership goes to the peer! (-> use shared ptr later...)
- _peer = new LegacyPeer(this, socket, this);
- // only in compat mode
- connect(_peer, SIGNAL(protocolVersionMismatch(int,int)), SLOT(onProtocolVersionMismatch(int,int)));
+ // read the list of protocols supported by the client
+ while (socket()->bytesAvailable() >= 4) {
+ quint32 data;
+ socket()->read((char*)&data, 4);
+ data = qFromBigEndian<quint32>(data);
+
+ Protocol::Type type = static_cast<Protocol::Type>(data & 0xff);
+ quint16 protoFeatures = static_cast<quint16>(data>>8 & 0xffff);
+ _supportedProtos.append(PeerFactory::ProtoDescriptor(type, protoFeatures));
+
+ if (data >= 0x80000000) { // last protocol
+ RemotePeer *peer = PeerFactory::createPeer(_supportedProtos, this, socket(), this);
+ if (peer->protocol() == Protocol::LegacyProtocol) {
+ _legacy = true;
+ connect(peer, SIGNAL(protocolVersionMismatch(int,int)), SLOT(onProtocolVersionMismatch(int,int)));
+ }
+ setPeer(peer);
+
+ // inform the client
+ quint32 reply = peer->protocol() | peer->enabledFeatures()<<8 | _connectionFeatures<<24;
+ reply = qToBigEndian<quint32>(reply);
+ socket()->write((char*)&reply, 4);
+ socket()->flush();
+
+ if (!_legacy && (_connectionFeatures & Protocol::Encryption))
+ startSsl(); // legacy peer enables it later
+ return;
+ }
+ }