PacketizedTCP.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "NativeFeatureIncludes.h"
  11. #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
  12. #include "PacketizedTCP.h"
  13. #include "NativeTypes.h"
  14. #include "BitStream.h"
  15. #include "MessageIdentifiers.h"
  16. #include "RakAlloca.h"
  17. using namespace RakNet;
  18. typedef uint32_t PTCPHeader;
  19. STATIC_FACTORY_DEFINITIONS(PacketizedTCP,PacketizedTCP);
  20. PacketizedTCP::PacketizedTCP()
  21. {
  22. }
  23. PacketizedTCP::~PacketizedTCP()
  24. {
  25. ClearAllConnections();
  26. }
  27. void PacketizedTCP::Stop(void)
  28. {
  29. unsigned int i;
  30. TCPInterface::Stop();
  31. for (i=0; i < waitingPackets.Size(); i++)
  32. DeallocatePacket(waitingPackets[i]);
  33. ClearAllConnections();
  34. }
  35. void PacketizedTCP::Send( const char *data, unsigned length, const SystemAddress &systemAddress, bool broadcast )
  36. {
  37. PTCPHeader dataLength;
  38. dataLength=length;
  39. #ifndef __BITSTREAM_NATIVE_END
  40. if (RakNet::BitStream::DoEndianSwap())
  41. RakNet::BitStream::ReverseBytes((unsigned char*) &length,(unsigned char*) &dataLength,sizeof(dataLength));
  42. #else
  43. dataLength=length;
  44. #endif
  45. unsigned int lengthsArray[2];
  46. const char *dataArray[2];
  47. dataArray[0]=(char*) &dataLength;
  48. dataArray[1]=data;
  49. lengthsArray[0]=sizeof(dataLength);
  50. lengthsArray[1]=length;
  51. TCPInterface::SendList(dataArray,lengthsArray,2,systemAddress,broadcast);
  52. }
  53. bool PacketizedTCP::SendList( const char **data, const unsigned int *lengths, const int numParameters, const SystemAddress &systemAddress, bool broadcast )
  54. {
  55. if (isStarted.GetValue()==0)
  56. return false;
  57. if (data==0)
  58. return false;
  59. if (systemAddress==UNASSIGNED_SYSTEM_ADDRESS && broadcast==false)
  60. return false;
  61. PTCPHeader totalLengthOfUserData=0;
  62. int i;
  63. for (i=0; i < numParameters; i++)
  64. {
  65. if (lengths[i]>0)
  66. totalLengthOfUserData+=lengths[i];
  67. }
  68. if (totalLengthOfUserData==0)
  69. return false;
  70. PTCPHeader dataLength;
  71. #ifndef __BITSTREAM_NATIVE_END
  72. if (RakNet::BitStream::DoEndianSwap())
  73. RakNet::BitStream::ReverseBytes((unsigned char*) &totalLengthOfUserData,(unsigned char*) &dataLength,sizeof(dataLength));
  74. #else
  75. dataLength=totalLengthOfUserData;
  76. #endif
  77. unsigned int lengthsArray[512];
  78. const char *dataArray[512];
  79. dataArray[0]=(char*) &dataLength;
  80. lengthsArray[0]=sizeof(dataLength);
  81. for (int i=0; i < 512 && i < numParameters; i++)
  82. {
  83. dataArray[i+1]=data[i];
  84. lengthsArray[i+1]=lengths[i];
  85. }
  86. return TCPInterface::SendList(dataArray,lengthsArray,numParameters+1,systemAddress,broadcast);
  87. }
  88. void PacketizedTCP::PushNotificationsToQueues(void)
  89. {
  90. SystemAddress sa;
  91. sa = TCPInterface::HasNewIncomingConnection();
  92. if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
  93. {
  94. _newIncomingConnections.Push(sa, _FILE_AND_LINE_ );
  95. AddToConnectionList(sa);
  96. }
  97. sa = TCPInterface::HasFailedConnectionAttempt();
  98. if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
  99. {
  100. _failedConnectionAttempts.Push(sa, _FILE_AND_LINE_ );
  101. }
  102. sa = TCPInterface::HasLostConnection();
  103. if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
  104. {
  105. _lostConnections.Push(sa, _FILE_AND_LINE_ );
  106. RemoveFromConnectionList(sa);
  107. }
  108. sa = TCPInterface::HasCompletedConnectionAttempt();
  109. if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
  110. {
  111. _completedConnectionAttempts.Push(sa, _FILE_AND_LINE_ );
  112. AddToConnectionList(sa);
  113. }
  114. }
  115. Packet* PacketizedTCP::Receive( void )
  116. {
  117. PushNotificationsToQueues();
  118. unsigned int i;
  119. for (i=0; i < messageHandlerList.Size(); i++)
  120. messageHandlerList[i]->Update();
  121. Packet *outgoingPacket=ReturnOutgoingPacket();
  122. if (outgoingPacket)
  123. return outgoingPacket;
  124. Packet *incomingPacket;
  125. incomingPacket = TCPInterface::ReceiveInt();
  126. unsigned int index;
  127. while (incomingPacket)
  128. {
  129. if (connections.Has(incomingPacket->systemAddress))
  130. index = connections.GetIndexAtKey(incomingPacket->systemAddress);
  131. else
  132. index=(unsigned int) -1;
  133. if ((unsigned int)index==(unsigned int)-1)
  134. {
  135. DeallocatePacket(incomingPacket);
  136. incomingPacket = TCPInterface::ReceiveInt();
  137. continue;
  138. }
  139. if (incomingPacket->deleteData==true)
  140. {
  141. // Came from network
  142. SystemAddress systemAddressFromPacket;
  143. if (index < connections.Size())
  144. {
  145. DataStructures::ByteQueue *bq = connections[index];
  146. // Buffer data
  147. bq->WriteBytes((const char*) incomingPacket->data,incomingPacket->length, _FILE_AND_LINE_);
  148. systemAddressFromPacket=incomingPacket->systemAddress;
  149. PTCPHeader dataLength;
  150. // Peek the header to see if a full message is waiting
  151. bq->ReadBytes((char*) &dataLength,sizeof(PTCPHeader),true);
  152. if (RakNet::BitStream::DoEndianSwap())
  153. RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &dataLength,sizeof(dataLength));
  154. // Header indicates packet length. If enough data is available, read out and return one packet
  155. if (bq->GetBytesWritten()>=dataLength+sizeof(PTCPHeader))
  156. {
  157. do
  158. {
  159. bq->IncrementReadOffset(sizeof(PTCPHeader));
  160. outgoingPacket = RakNet::OP_NEW<Packet>(_FILE_AND_LINE_);
  161. outgoingPacket->length=dataLength;
  162. outgoingPacket->bitSize=BYTES_TO_BITS(dataLength);
  163. outgoingPacket->guid=UNASSIGNED_RAKNET_GUID;
  164. outgoingPacket->systemAddress=systemAddressFromPacket;
  165. outgoingPacket->deleteData=false; // Did not come from the network
  166. outgoingPacket->data=(unsigned char*) rakMalloc_Ex(dataLength, _FILE_AND_LINE_);
  167. if (outgoingPacket->data==0)
  168. {
  169. notifyOutOfMemory(_FILE_AND_LINE_);
  170. RakNet::OP_DELETE(outgoingPacket,_FILE_AND_LINE_);
  171. return 0;
  172. }
  173. bq->ReadBytes((char*) outgoingPacket->data,dataLength,false);
  174. waitingPackets.Push(outgoingPacket, _FILE_AND_LINE_ );
  175. // Peek the header to see if a full message is waiting
  176. if (bq->ReadBytes((char*) &dataLength,sizeof(PTCPHeader),true))
  177. {
  178. if (RakNet::BitStream::DoEndianSwap())
  179. RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &dataLength,sizeof(dataLength));
  180. }
  181. else
  182. break;
  183. } while (bq->GetBytesWritten()>=dataLength+sizeof(PTCPHeader));
  184. }
  185. else
  186. {
  187. unsigned int oldWritten = bq->GetBytesWritten()-incomingPacket->length;
  188. unsigned int newWritten = bq->GetBytesWritten();
  189. // Return ID_DOWNLOAD_PROGRESS
  190. if (newWritten/65536!=oldWritten/65536)
  191. {
  192. outgoingPacket = RakNet::OP_NEW<Packet>(_FILE_AND_LINE_);
  193. outgoingPacket->length=sizeof(MessageID) +
  194. sizeof(unsigned int)*2 +
  195. sizeof(unsigned int) +
  196. 65536;
  197. outgoingPacket->bitSize=BYTES_TO_BITS(incomingPacket->length);
  198. outgoingPacket->guid=UNASSIGNED_RAKNET_GUID;
  199. outgoingPacket->systemAddress=incomingPacket->systemAddress;
  200. outgoingPacket->deleteData=false;
  201. outgoingPacket->data=(unsigned char*) rakMalloc_Ex(outgoingPacket->length, _FILE_AND_LINE_);
  202. if (outgoingPacket->data==0)
  203. {
  204. notifyOutOfMemory(_FILE_AND_LINE_);
  205. RakNet::OP_DELETE(outgoingPacket,_FILE_AND_LINE_);
  206. return 0;
  207. }
  208. outgoingPacket->data[0]=(MessageID)ID_DOWNLOAD_PROGRESS;
  209. unsigned int totalParts=dataLength/65536;
  210. unsigned int partIndex=newWritten/65536;
  211. unsigned int oneChunkSize=65536;
  212. memcpy(outgoingPacket->data+sizeof(MessageID), &partIndex, sizeof(unsigned int));
  213. memcpy(outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*1, &totalParts, sizeof(unsigned int));
  214. memcpy(outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*2, &oneChunkSize, sizeof(unsigned int));
  215. bq->IncrementReadOffset(sizeof(PTCPHeader));
  216. bq->ReadBytes((char*) outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*3,oneChunkSize,true);
  217. bq->DecrementReadOffset(sizeof(PTCPHeader));
  218. waitingPackets.Push(outgoingPacket, _FILE_AND_LINE_ );
  219. }
  220. }
  221. }
  222. DeallocatePacket(incomingPacket);
  223. incomingPacket=0;
  224. }
  225. else
  226. waitingPackets.Push(incomingPacket, _FILE_AND_LINE_ );
  227. incomingPacket = TCPInterface::ReceiveInt();
  228. }
  229. return ReturnOutgoingPacket();
  230. }
  231. Packet *PacketizedTCP::ReturnOutgoingPacket(void)
  232. {
  233. Packet *outgoingPacket=0;
  234. unsigned int i;
  235. while (outgoingPacket==0 && waitingPackets.IsEmpty()==false)
  236. {
  237. outgoingPacket=waitingPackets.Pop();
  238. PluginReceiveResult pluginResult;
  239. for (i=0; i < messageHandlerList.Size(); i++)
  240. {
  241. pluginResult=messageHandlerList[i]->OnReceive(outgoingPacket);
  242. if (pluginResult==RR_STOP_PROCESSING_AND_DEALLOCATE)
  243. {
  244. DeallocatePacket( outgoingPacket );
  245. outgoingPacket=0; // Will do the loop again and get another packet
  246. break; // break out of the enclosing for
  247. }
  248. else if (pluginResult==RR_STOP_PROCESSING)
  249. {
  250. outgoingPacket=0;
  251. break;
  252. }
  253. }
  254. }
  255. return outgoingPacket;
  256. }
  257. void PacketizedTCP::CloseConnection( SystemAddress systemAddress )
  258. {
  259. RemoveFromConnectionList(systemAddress);
  260. TCPInterface::CloseConnection(systemAddress);
  261. }
  262. void PacketizedTCP::RemoveFromConnectionList(const SystemAddress &sa)
  263. {
  264. if (sa==UNASSIGNED_SYSTEM_ADDRESS)
  265. return;
  266. if (connections.Has(sa))
  267. {
  268. unsigned int index = connections.GetIndexAtKey(sa);
  269. if (index!=(unsigned int)-1)
  270. {
  271. RakNet::OP_DELETE(connections[index],_FILE_AND_LINE_);
  272. connections.RemoveAtIndex(index);
  273. }
  274. }
  275. }
  276. void PacketizedTCP::AddToConnectionList(const SystemAddress &sa)
  277. {
  278. if (sa==UNASSIGNED_SYSTEM_ADDRESS)
  279. return;
  280. connections.SetNew(sa, RakNet::OP_NEW<DataStructures::ByteQueue>(_FILE_AND_LINE_));
  281. }
  282. void PacketizedTCP::ClearAllConnections(void)
  283. {
  284. unsigned int i;
  285. for (i=0; i < connections.Size(); i++)
  286. RakNet::OP_DELETE(connections[i],_FILE_AND_LINE_);
  287. connections.Clear();
  288. }
  289. SystemAddress PacketizedTCP::HasCompletedConnectionAttempt(void)
  290. {
  291. PushNotificationsToQueues();
  292. if (_completedConnectionAttempts.IsEmpty()==false)
  293. return _completedConnectionAttempts.Pop();
  294. return UNASSIGNED_SYSTEM_ADDRESS;
  295. }
  296. SystemAddress PacketizedTCP::HasFailedConnectionAttempt(void)
  297. {
  298. PushNotificationsToQueues();
  299. if (_failedConnectionAttempts.IsEmpty()==false)
  300. return _failedConnectionAttempts.Pop();
  301. return UNASSIGNED_SYSTEM_ADDRESS;
  302. }
  303. SystemAddress PacketizedTCP::HasNewIncomingConnection(void)
  304. {
  305. PushNotificationsToQueues();
  306. if (_newIncomingConnections.IsEmpty()==false)
  307. return _newIncomingConnections.Pop();
  308. return UNASSIGNED_SYSTEM_ADDRESS;
  309. }
  310. SystemAddress PacketizedTCP::HasLostConnection(void)
  311. {
  312. PushNotificationsToQueues();
  313. if (_lostConnections.IsEmpty()==false)
  314. return _lostConnections.Pop();
  315. return UNASSIGNED_SYSTEM_ADDRESS;
  316. }
  317. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号