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
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
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
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
00101 out->Write((MessageID)ID_ROUTE_AND_MULTICAST);
00102
00103
00104 out->WriteCompressed((unsigned char)priority);
00105 out->WriteCompressed((unsigned char)reliability);
00106 out->WriteCompressed((unsigned char)orderingChannel);
00107
00108
00109 out->Write((unsigned int)bitLength);
00110
00111
00112
00113 out->AlignWriteToByteBoundary();
00114
00115
00116
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
00123 outputOffset=out->GetWriteOffset();
00124
00125
00126 unsigned i;
00127 for (i=0; i < tree->children.Size(); i++)
00128 {
00129
00130 out->SetWriteOffset(outputOffset);
00131
00132
00133 out->Write(rakPeerInterface->GetExternalID(tree->children[i]->data.systemAddress));
00134
00135
00136 SerializePreorder(tree->children[i], out, recipients);
00137
00138
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
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);
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;
00199 }
00200
00201 incomingBitstream.Read(originalSender);
00202 out.Write(originalSender);
00203 outStartingOffset=out.GetWriteOffset();
00204
00205
00206 bool hasData=false;
00207 SystemAddress recipient;
00208 unsigned short numberOfChildren;
00209 incomingBitstream.Read(hasData);
00210 incomingBitstream.Read(recipient);
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
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
00253 SendUnified(&out, priority, reliability, orderingChannel, immediateRecipient, false);
00254
00255
00256 out.SetWriteOffset(outStartingOffset);
00257
00258
00259 immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS;
00260
00261 pendingNodeCount=0;
00262
00263 }
00264
00265
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
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_*