diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index 4a8aba985..ec704dfab 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -776,6 +776,9 @@ int p3turtle::handleIncoming() case RS_TURTLE_SUBTYPE_TUNNEL_OK : handleTunnelResult(dynamic_cast(item)) ; break ; + + case RS_TURTLE_SUBTYPE_GENERIC_DATA : handleRecvGenericDataItem(dynamic_cast(item)) ; + break ; default: std::cerr << "p3turtle::handleIncoming: Unknown packet subtype " << item->PacketSubType() << std::endl ; } @@ -1076,48 +1079,66 @@ void p3turtle::handleRecvGenericTunnelItem(RsTurtleGenericTunnelItem *item) std::string vpid ; RsTurtleClientService *service ; - // Now lock the router - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it2(_local_tunnels.find(item->tunnelId())) ; - - if(it2 == _local_tunnels.end()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: got file CRC32 map with unknown tunnel id " << (void*)item->tunnelId() << std::endl ; -#endif - return ; - } - - TurtleTunnel& tunnel(it2->second) ; - -#ifdef P3TURTLE_DEBUG - assert(!tunnel.hash.empty()) ; - - std::cerr << " This is an endpoint for this file map." << std::endl ; - std::cerr << " Forwarding data to the multiplexer." << std::endl ; - std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ; -#endif - // We should check that there is no backward call to the turtle router! - // - vpid = tunnel.vpid ; - hash = tunnel.hash ; - - std::map::const_iterator it = _incoming_file_hashes.find(hash) ; - - if(it == _incoming_file_hashes.end()) - { - std::cerr << "p3turtle::handleRecvGenericTunnelItem(): hash " << hash << " for tunnel " << (void*)(it2->first) << " has no attached service! Dropping the item. This is a serious consistency error." << std::endl; - return ; - } - - service = it->second.service ; - } + if(!getTunnelServiceInfo(item->tunnelId(),vpid,hash,service)) + return ; service->receiveTurtleData(item,hash,vpid,item->travelingDirection()) ; } +void p3turtle::handleRecvGenericDataItem(RsTurtleGenericDataItem *item) +{ +#ifdef P3TURTLE_DEBUG + std::cerr << "p3Turtle: received Generic Data item:" << std::endl ; + item->print(std::cerr,1) ; +#endif + std::string virtual_peer_id ; + std::string hash ; + RsTurtleClientService *service ; + + if(!getTunnelServiceInfo(item->tunnelId(),virtual_peer_id,hash,service)) + return ; + + service->receiveTurtleData(item->data_bytes,item->data_size,hash,virtual_peer_id,item->travelingDirection()) ; +} + +bool p3turtle::getTunnelServiceInfo(TurtleTunnelId tunnel_id,std::string& vpid,std::string& hash,RsTurtleClientService *& service) +{ + RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ + + std::map::iterator it2(_local_tunnels.find(tunnel_id)) ; + + if(it2 == _local_tunnels.end()) + { +#ifdef P3TURTLE_DEBUG + std::cerr << "p3turtle: got file CRC32 map with unknown tunnel id " << (void*)item->tunnelId() << std::endl ; +#endif + return false; + } + + TurtleTunnel& tunnel(it2->second) ; + +#ifdef P3TURTLE_DEBUG + assert(!tunnel.hash.empty()) ; + + std::cerr << " This is an endpoint for this file map." << std::endl ; + std::cerr << " Forwarding data to the multiplexer." << std::endl ; + std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ; +#endif + // We should check that there is no backward call to the turtle router! + // + vpid = tunnel.vpid ; + hash = tunnel.hash ; + + std::map::const_iterator it = _incoming_file_hashes.find(hash) ; + + if(it == _incoming_file_hashes.end()) + { + std::cerr << "p3turtle::handleRecvGenericTunnelItem(): hash " << hash << " for tunnel " << (void*)(it2->first) << " has no attached service! Dropping the item. This is a serious consistency error." << std::endl; + return false; + } + + service = it->second.service ; +} // Send a data request into the correct tunnel for the given file hash // void p3turtle::sendTurtleData(const std::string& virtual_peer_id,RsTurtleGenericTunnelItem *item) diff --git a/libretroshare/src/turtle/p3turtle.h b/libretroshare/src/turtle/p3turtle.h index b8ae97452..a6b86918c 100644 --- a/libretroshare/src/turtle/p3turtle.h +++ b/libretroshare/src/turtle/p3turtle.h @@ -352,6 +352,8 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config /// specific routing functions for handling particular packets. void handleRecvGenericTunnelItem(RsTurtleGenericTunnelItem *item); + void handleRecvGenericDataItem(RsTurtleGenericDataItem *item); + bool getTunnelServiceInfo(TurtleTunnelId, std::string& virtual_peer_id, std::string& hash, RsTurtleClientService*&) ; // following functions should go to ftServer void handleSearchRequest(RsTurtleSearchRequestItem *item); diff --git a/libretroshare/src/turtle/rsturtleitem.cc b/libretroshare/src/turtle/rsturtleitem.cc index ad5a66fd5..192ec0e90 100644 --- a/libretroshare/src/turtle/rsturtleitem.cc +++ b/libretroshare/src/turtle/rsturtleitem.cc @@ -91,6 +91,17 @@ uint32_t RsTurtleTunnelOkItem::serial_size() return s ; } +uint32_t RsTurtleGenericDataItem::serial_size() +{ + uint32_t s = 0 ; + + s += 8 ; // header + s += 4 ; // tunnel id + s += 4 ; // data size + s += data_size ; // data + + return s ; +} // // ---------------------------------- Serialization ----------------------------------// // @@ -122,18 +133,8 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size) case RS_TURTLE_SUBTYPE_SEARCH_RESULT : return new RsTurtleSearchResultItem(data,*size) ; case RS_TURTLE_SUBTYPE_OPEN_TUNNEL : return new RsTurtleOpenTunnelItem(data,*size) ; case RS_TURTLE_SUBTYPE_TUNNEL_OK : return new RsTurtleTunnelOkItem(data,*size) ; + case RS_TURTLE_SUBTYPE_GENERIC_DATA : return new RsTurtleGenericDataItem(data,*size) ; - // We need to call some client serialiser from there. - // - // case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem(data,*size) ; - // case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem(data,*size) ; - // case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem(data,*size) ; - // case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem(data,*size) ; - // case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST : return new RsTurtleFileCrcRequestItem(data,*size) ; - // case RS_TURTLE_SUBTYPE_FILE_CRC : return new RsTurtleFileCrcItem(data,*size) ; - // case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem(data,*size) ; - // case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem(data,*size) ; - default: break ; } @@ -520,6 +521,84 @@ RsTurtleTunnelOkItem::RsTurtleTunnelOkItem(void *data,uint32_t pktsize) #endif } +RsTurtleGenericDataItem::RsTurtleGenericDataItem(void *data,uint32_t pktsize) + : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_DATA) +{ + setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_DATA) ; +#ifdef P3TURTLE_DEBUG + std::cerr << " type = tunnel ok" << std::endl ; +#endif + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + + /* add mandatory parts first */ + + bool ok = true ; + uint32_t data_size = 0; + + ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ; + ok &= getRawUInt32(data, pktsize, &offset, &data_size); +#ifdef P3TURTLE_DEBUG + std::cerr << " request_id=" << (void*)request_id << ", tunnel_id=" << (void*)tunnel_id << std::endl ; +#endif + data_bytes = malloc(data_size) ; + + if(data_bytes != NULL) + { + memcpy(data_bytes,data+offset,data_size) ; + offset += data_size ; + } + else + { + std::cerr << "(EE) RsTurtleGenericDataItem: Error. Cannot allocate data for a size of " << data_size << " bytes." <