• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Router.cpp

Go to the documentation of this file.
00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_Router==1
00003 
00004 #include "Router.h"
00005 #include "BitStream.h"
00006 #include "RakPeerInterface.h"
00007 #include "MessageIdentifiers.h"
00008 #include "RakAssert.h"
00009 
00010 //#define _DO_PRINTF
00011 
00012 #ifdef _DO_PRINTF
00013 #include <stdio.h>
00014 #endif
00015 
00016 #ifdef _MSC_VER
00017 #pragma warning( push )
00018 #endif
00019 
00020 Router::Router()
00021 {
00022         graph=0;
00023         restrictByType=false;
00024         DataStructures::OrderedList<unsigned char,unsigned char>::IMPLEMENT_DEFAULT_COMPARISON();
00025 }
00026 Router::~Router()
00027 {
00028 }
00029 void Router::SetRestrictRoutingByType(bool restrict__)
00030 {
00031         restrictByType=restrict__;
00032 }
00033 void Router::AddAllowedType(unsigned char messageId)
00034 {
00035         if (allowedTypes.HasData(messageId)==false)
00036                 allowedTypes.Insert(messageId,messageId, true, __FILE__,__LINE__);
00037 }
00038 void Router::RemoveAllowedType(unsigned char messageId)
00039 {
00040         if (allowedTypes.HasData(messageId)==true)
00041                 allowedTypes.Remove(messageId);
00042 }
00043 void Router::SetConnectionGraph(DataStructures::WeightedGraph<ConnectionGraph::SystemAddressAndGroupId, unsigned short, false> *connectionGraph)
00044 {
00045         graph=connectionGraph;
00046 }
00047 bool Router::Send( const char *data, BitSize_t bitLength, PacketPriority priority, PacketReliability reliability, char orderingChannel, SystemAddress systemAddress )
00048 {
00049         if (systemAddress!=UNASSIGNED_SYSTEM_ADDRESS)
00050         {
00051                 RakAssert(data);
00052                 RakAssert(bitLength);
00053                 // Prevent recursion in case a routing call itself calls the router
00054                 if (bitLength>=8 && data[0]==ID_ROUTE_AND_MULTICAST)
00055                         return false;
00056 
00057                 SystemAddressList systemAddressList;
00058                 systemAddressList.AddSystem(systemAddress);
00059                 return Send((char*)data, bitLength, priority, reliability, orderingChannel, &systemAddressList);
00060         }
00061         return false;   
00062 }
00063 bool Router::Send( char *data, BitSize_t bitLength, PacketPriority priority, PacketReliability reliability, char orderingChannel, SystemAddressList *recipients )
00064 {
00065         RakAssert(data);
00066         RakAssert(bitLength);
00067         if (recipients->GetList()->Size()==0)
00068                 return false;
00069         if (bitLength==0)
00070                 return false;
00071         DataStructures::Tree<ConnectionGraph::SystemAddressAndGroupId> tree;
00072         SystemAddress root;
00073         root = rakPeerInterface->GetExternalID(rakPeerInterface->GetSystemAddressFromIndex(0));
00074         if (root==UNASSIGNED_SYSTEM_ADDRESS)
00075                 return false;
00076         DataStructures::List<ConnectionGraph::SystemAddressAndGroupId> recipientList;
00077         unsigned i;
00078         for (i=0; i < recipients->Size(); i++)
00079                 recipientList.Insert(ConnectionGraph::SystemAddressAndGroupId(recipients->GetList()->operator [](i),0, UNASSIGNED_RAKNET_GUID), __FILE__, __LINE__);
00080         if (graph->GetSpanningTree(tree, &recipientList, ConnectionGraph::SystemAddressAndGroupId(root,0,UNASSIGNED_RAKNET_GUID), 65535)==false)
00081                 return false;
00082 
00083         RakNet::BitStream out;
00084 
00085         // Write timestamp first, if the user had a timestamp
00086         if (data[0]==ID_TIMESTAMP && bitLength >= BYTES_TO_BITS(sizeof(MessageID)+sizeof(RakNetTime)))
00087         {
00088                 out.Write(data, sizeof(MessageID)+sizeof(RakNetTime));
00089                 data+=sizeof(MessageID)+sizeof(RakNetTime);
00090                 bitLength-=BYTES_TO_BITS(sizeof(MessageID)+sizeof(RakNetTime));
00091         }
00092 
00093         SendTree(priority, reliability, orderingChannel, &tree, data, bitLength, &out, recipients);
00094         return true;
00095 }
00096 void Router::SendTree(PacketPriority priority, PacketReliability reliability, char orderingChannel, DataStructures::Tree<ConnectionGraph::SystemAddressAndGroupId> *tree, const char *data, BitSize_t bitLength, RakNet::BitStream *out, SystemAddressList *recipients)
00097 {
00098         BitSize_t outputOffset;
00099 
00100         // Write routing identifer
00101         out->Write((MessageID)ID_ROUTE_AND_MULTICAST);
00102 
00103         // Write the send parameters
00104         out->WriteCompressed((unsigned char)priority);
00105         out->WriteCompressed((unsigned char)reliability);
00106         out->WriteCompressed((unsigned char)orderingChannel);
00107 
00108         // Write the user payload length
00109         out->Write((unsigned int)bitLength);
00110 //      out->PrintBits();
00111 //      payload->PrintBits();
00112 
00113         out->AlignWriteToByteBoundary();
00114 //      payload->AlignReadToByteBoundary();
00115 //      out->Write(payload, payload->GetNumberOfUnreadBits());
00116 //      out->PrintBits();
00117         if ((bitLength % 8)==0)
00118                 out->Write(data, BITS_TO_BYTES(bitLength));
00119         else
00120                 out->WriteBits((const unsigned char*)data, bitLength, false);
00121 
00122         // Save where to start writing per-system data
00123         outputOffset=out->GetWriteOffset();
00124 
00125         // Write every child of the root of the tree (SystemAddress, isRecipient, branch)
00126         unsigned i;
00127         for (i=0; i < tree->children.Size(); i++)
00128         {
00129                 // Start writing at the per-system data byte
00130                 out->SetWriteOffset(outputOffset);
00131 
00132                 // Write our external IP to designate the sender
00133                 out->Write(rakPeerInterface->GetExternalID(tree->children[i]->data.systemAddress));
00134 
00135                 // Serialize the tree
00136                 SerializePreorder(tree->children[i], out, recipients);
00137 
00138                 // Send to the first hop
00139 #ifdef _DO_PRINTF
00140                 RAKNET_DEBUG_PRINTF("%i sending to %i\n", rakPeerInterface->GetExternalID(tree->children[i]->data.systemAddress).port, tree->children[i]->data.systemAddress.port);
00141 #endif
00142                 SendUnified(out, priority, reliability, orderingChannel, tree->children[i]->data.systemAddress, false);
00143         }
00144 }
00145 PluginReceiveResult Router::OnReceive(Packet *packet)
00146 {
00147         if (packet->data[0]==ID_ROUTE_AND_MULTICAST ||
00148                 (packet->length>5 && packet->data[0]==ID_TIMESTAMP && packet->data[5]==ID_ROUTE_AND_MULTICAST))
00149         {
00150 #ifdef _DO_PRINTF
00151                 RAKNET_DEBUG_PRINTF("%i got routed message from %i\n", peer->GetExternalID(packet->systemAddress).port, packet->systemAddress.port);
00152 #endif
00153                 RakNetTime timestamp;
00154                 PacketPriority priority;
00155                 PacketReliability reliability;
00156                 unsigned char orderingChannel;
00157                 SystemAddress originalSender;
00158                 RakNet::BitStream out;
00159                 BitSize_t outStartingOffset;
00160                 unsigned int payloadBitLength;
00161                 unsigned payloadWriteByteOffset;
00162                 RakNet::BitStream incomingBitstream(packet->data, packet->length, false);
00163                 incomingBitstream.IgnoreBits(8);
00164                 
00165                 if (packet->data[0]==ID_TIMESTAMP)
00166                 {
00167                         incomingBitstream.Read(timestamp);
00168                         out.Write((MessageID)ID_TIMESTAMP);
00169                         out.Write(timestamp);
00170                         incomingBitstream.IgnoreBits(8);
00171                 }
00172 
00173                 // Read the send parameters
00174                 unsigned char c;
00175                 incomingBitstream.ReadCompressed(c);
00176                 priority=(PacketPriority)c;
00177                 incomingBitstream.ReadCompressed(c);
00178                 reliability=(PacketReliability)c;
00179                 incomingBitstream.ReadCompressed(orderingChannel);
00180                 incomingBitstream.Read(payloadBitLength);
00181                 
00182                 out.Write((MessageID)ID_ROUTE_AND_MULTICAST);
00183                 out.WriteCompressed((unsigned char)priority);
00184                 out.WriteCompressed((unsigned char)reliability);
00185                 out.WriteCompressed((unsigned char)orderingChannel);
00186                 out.Write(payloadBitLength);
00187                 out.AlignWriteToByteBoundary();
00188                 incomingBitstream.AlignReadToByteBoundary();
00189                 payloadWriteByteOffset=(unsigned int) BITS_TO_BYTES(out.GetWriteOffset());
00190                 out.Write(&incomingBitstream, payloadBitLength); // This write also does a read on incomingBitStream
00191 
00192                 if (restrictByType)
00193                 {
00194                         RakNet::BitStream t(out.GetData()+payloadWriteByteOffset, sizeof(unsigned char), false);
00195                         MessageID messageID;
00196                         t.Read(messageID);
00197                         if (allowedTypes.HasData(messageID)==false)
00198                                 return RR_STOP_PROCESSING_AND_DEALLOCATE; // Don't route restricted types
00199                 }
00200 
00201                 incomingBitstream.Read(originalSender);
00202                 out.Write(originalSender);
00203                 outStartingOffset=out.GetWriteOffset();
00204 
00205                 // Deserialize the root
00206                 bool hasData=false;
00207                 SystemAddress recipient;
00208                 unsigned short numberOfChildren;
00209                 incomingBitstream.Read(hasData);
00210                 incomingBitstream.Read(recipient); // This should be our own address
00211                 if (incomingBitstream.ReadCompressed(numberOfChildren)==false)
00212                 {
00213 #ifdef _DEBUG
00214                         RakAssert(0);
00215 #endif
00216                         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00217                 }
00218 
00219                 unsigned childIndex;
00220                 bool childHasData=false;
00221                 SystemAddress childRecipient;
00222                 unsigned short childNumberOfChildren;
00223                 SystemAddress immediateRecipient;
00224                 immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS;
00225                 int pendingNodeCount=0;
00226 
00227                 for (childIndex=0; childIndex < numberOfChildren; childIndex++)
00228                 {
00229                         while (pendingNodeCount!=-1)
00230                         {
00231                                 // Copy out the serialized subtree for this child
00232                                 incomingBitstream.Read(childHasData);
00233                                 incomingBitstream.Read(childRecipient);
00234                                 if (!incomingBitstream.ReadCompressed(childNumberOfChildren))
00235                                         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00236                                 if (immediateRecipient==UNASSIGNED_SYSTEM_ADDRESS)
00237                                 {
00238                                         immediateRecipient=childRecipient;
00239                                 }
00240 
00241                                 pendingNodeCount+=childNumberOfChildren-1;
00242 
00243                                 out.Write(childHasData);
00244                                 out.Write(childRecipient);
00245                                 out.WriteCompressed(childNumberOfChildren);
00246                         }
00247 
00248 #ifdef _DO_PRINTF
00249                         RAKNET_DEBUG_PRINTF("%i routing to %i\n", peer->GetExternalID(packet->systemAddress).port, immediateRecipient.port);
00250 #endif
00251 
00252                         // Send what we got so far
00253                         SendUnified(&out, priority, reliability, orderingChannel, immediateRecipient, false);
00254 
00255                         // Restart writing the per recipient data
00256                         out.SetWriteOffset(outStartingOffset);
00257 
00258                         // Reread the top level node
00259                         immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS;
00260 
00261                         pendingNodeCount=0;
00262 
00263                 }
00264 
00265                 // Write the user payload to the packet struct if this is a destination and change the sender and return true
00266                 if (hasData)
00267                 {
00268 #ifdef _DO_PRINTF
00269                         RAKNET_DEBUG_PRINTF("%i returning payload to user\n", peer->GetExternalID(packet->systemAddress).port);
00270 #endif
00271 
00272                         if (packet->data[0]==ID_TIMESTAMP )
00273                         {
00274                                 memcpy( packet->data + sizeof(RakNetTime)+sizeof(unsigned char), out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) );
00275                                 packet->bitSize=BYTES_TO_BITS(sizeof(RakNetTime)+sizeof(unsigned char))+payloadBitLength;
00276                         }
00277                         else
00278                         {
00279                                 memcpy( packet->data, out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) );
00280                                 packet->bitSize=payloadBitLength;
00281                         }
00282                         packet->length=(unsigned int) BITS_TO_BYTES(packet->bitSize);
00283                         packet->systemAddress.systemIndex=(SystemIndex)-1;
00284                         packet->systemAddress=originalSender;
00285 
00286                         return RR_CONTINUE_PROCESSING;
00287                 }
00288 
00289                 // Absorb
00290                 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00291         }
00292 
00293         return RR_CONTINUE_PROCESSING;
00294 }
00295 void Router::OnAttach(void)
00296 {
00297         rakPeerInterface->SetRouterInterface(this);
00298 }
00299 void Router::OnDetach(void)
00300 {
00301         rakPeerInterface->RemoveRouterInterface(this);
00302 }
00303 void Router::SerializePreorder(DataStructures::Tree<ConnectionGraph::SystemAddressAndGroupId> *tree, RakNet::BitStream *out, SystemAddressList *recipients) const
00304 {
00305         unsigned i;
00306         out->Write((bool) (recipients->GetList()->GetIndexOf(tree->data.systemAddress)!=MAX_UNSIGNED_LONG));
00307         out->Write(tree->data.systemAddress);
00308         out->WriteCompressed((unsigned short) tree->children.Size());
00309         for (i=0; i < tree->children.Size(); i++)
00310                 SerializePreorder(tree->children[i], out, recipients);
00311 }
00312 
00313 #ifdef _MSC_VER
00314 #pragma warning( pop )
00315 #endif
00316 
00317 #endif // _RAKNET_SUPPORT_*

Generated on Thu Sep 30 2010 01:27:28 for RakNet by  doxygen 1.7.1