void ServerConnection::packetHandler(PacketReader& packet) { UInt8 marker = packet.read8(); if(marker!=0x0b) { ERROR("ServerConnection with an unknown %u marker, it should be 0x0b",marker); return; } packet.next(2); UInt8 id = packet.read8(); switch(id) { case 0x71: { packet.next(2); string tag; packet.readString8(tag); map<string,P2PHandshakerAddress>::iterator it = _p2pHandshakers.find(tag); if(it==_p2pHandshakers.end()) { ERROR("Unknown ServerConnection tag %s on P2P handshake",tag.c_str()); break; } (SocketAddress&)_handshake.peer.address = it->second; packet.reset(0); PacketWriter writer(packet.current(),packet.available()+16); // +16 for futur 0xFFFF padding writer.clear(packet.available()); _handshake.send(writer); _p2pHandshakers.erase(it); break; } case 0x40: { if(!_connected) { // Edge hello response _connected=true; return; } // Edge keepalive PacketWriter& packet(writer()); packet.write8(0x41); packet.write16(0); flush(); INFO("Keepalive RTMFP server"); break; } case 0x45: { // Server is death! (bool&)died=true; break; } default: ERROR("Unkown ServerConnection packet id %u",id); } }
// TODO make perhaps a FlowHandshake UInt8 Handshake::handshakeHandler(UInt8 id,PacketReader& request,PacketWriter& response) { switch(id){ case 0x30: { request.read8(); // passer un caractere (boite dans boite) UInt8 epdLen = request.read8()-1; UInt8 type = request.read8(); string epd; request.readRaw(epdLen,epd); string tag; request.readRaw(16,tag); response.writeString8(tag); // UDP hole punching if(type == 0x0f) return _gateway.p2pHandshake(tag,response,peer().address,(const UInt8*)epd.c_str()); if(type == 0x0a){ /// Handshake // RESPONSE 38 // New Cookie char cookie[65]; RandomInputStream ris; ris.read(cookie,64); cookie[64]='\0'; response.write8(64); response.writeRaw(cookie,64); _cookies[cookie] = new Cookie(epd); // instance id (certificat in the middle) response.writeRaw(_certificat,sizeof(_certificat)); return 0x70; } else { ERROR("Unkown handshake first way with '%02x' type",type); } break; } case 0x38: { _farId = request.read32(); string cookie; request.readRaw(request.read8(),cookie); map<string,Cookie*>::iterator itCookie = _cookies.find(cookie.c_str()); if(itCookie==_cookies.end()) { ERROR("Handshake cookie '%s' unknown",cookie.c_str()); return 0; } request.read8(); // why 0x81? // signature string farSignature; request.readString8(farSignature); // 81 02 1D 02 stable // farPubKeyPart UInt8 farPubKeyPart[128]; request.readRaw((char*)farPubKeyPart,sizeof(farPubKeyPart)); string farCertificat; request.readString8(farCertificat); // peerId = SHA256(farSignature+farPubKey) string temp(farSignature); temp.append((char*)farPubKeyPart,sizeof(farPubKeyPart)); EVP_Digest(temp.c_str(),temp.size(),(UInt8*)peer().id,NULL,EVP_sha256(),NULL); // Compute Diffie-Hellman secret UInt8 pubKey[128]; UInt8 sharedSecret[128]; RTMFP::EndDiffieHellman(RTMFP::BeginDiffieHellman(pubKey),farPubKeyPart,sharedSecret); // Compute Keys UInt8 requestKey[AES_KEY_SIZE]; UInt8 responseKey[AES_KEY_SIZE]; RTMFP::ComputeAsymetricKeys(sharedSecret,pubKey,_signature,farCertificat,requestKey,responseKey); // RESPONSE Util::UnpackUrl(itCookie->second->queryUrl,(string&)peer().path,(map<string,string>&)peer().parameters); response << _gateway.createSession(_farId,peer(),requestKey,responseKey); response.write8(0x81); response.writeString8(_signature); response.writeRaw((char*)pubKey,sizeof(pubKey)); response.write8(0x58); // remove cookie _cookies.erase(itCookie); // db_add_public(s); // TODO return 0x78; } default: ERROR("Unkown handshake packet id '%02x'",id); } return 0; }