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); if(type == 0x0f) return _gateway.p2pHandshake(tag,response,peer.address,(const UInt8*)epd.c_str()); if(type == 0x0a){ /// Handshake HelloAttempt& attempt = helloAttempt<HelloAttempt>(tag); // Fill peer infos UInt16 port; string host; Util::UnpackUrl(epd,host,port,(string&)peer.path,(map<string,string>&)peer.properties); set<string> addresses; peer.onHandshake(attempt.count+1,addresses); if(!addresses.empty()) { set<string>::iterator it; for(it=addresses.begin();it!=addresses.end();++it) { try { if((*it)=="again") ((string&)*it).assign(format("%s:%hu",host,port)); SocketAddress address(*it); response.writeAddress(address,it==addresses.begin()); } catch(Exception& ex) { ERROR("Bad redirection address %s in hello attempt, %s",(*it)=="again" ? epd.c_str() : (*it).c_str(),ex.displayText().c_str()); } } return 0x71; } // New Cookie createCookie(response,attempt,tag,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: { (UInt32&)farId = request.read32(); if(request.read7BitLongValue()!=COOKIE_SIZE) { ERROR("Bad handshake cookie '%s': its size should be 64 bytes",Util::FormatHex(request.current(),COOKIE_SIZE).c_str()); return 0; } map<const UInt8*,Cookie*,CompareCookies>::iterator itCookie = _cookies.find(request.current()); if(itCookie==_cookies.end()) { WARN("Cookie %s unknown, maybe already connected (udpBuffer congested?)",Util::FormatHex(request.current(),COOKIE_SIZE).c_str()); return 0; } Cookie& cookie(*itCookie->second); (SocketAddress&)cookie.peerAddress = peer.address; if(cookie.farId==0) { ((UInt32&)cookie.farId) = farId; request.next(COOKIE_SIZE); size_t size = (size_t)request.read7BitLongValue(); // peerId = SHA256(farPubKey) EVP_Digest(request.current(),size,(UInt8*)cookie.peerId,NULL,EVP_sha256(),NULL); cookie.initiatorKey().resize(request.read7BitValue()-2); request.next(2); // unknown request.readRaw(&cookie.initiatorKey()[0],cookie.initiatorKey().size()); cookie.initiatorNonce().resize(request.read7BitValue()); request.readRaw(&cookie.initiatorNonce()[0],cookie.initiatorNonce().size()); cookie.computeKeys(); } else if(cookie.id>0) { // Repeat cookie reponse! cookie.read(response); return 0x78; } // else Keys are computing (multi-thread) break; } default: ERROR("Unkown handshake packet id %u",id); } return 0; }