* Try to put queued up data on the socket. * * Control packets have higher priority, and will be sent first, if possible. * Standard packets can be split up in several package containers. In that case * all the parts of a split package must be sent in a row, without any control packet * in between. * * @param maxNumberOfBytesToSend This is the maximum number of bytes that is allowed to be p
| 465 | * @return the actual number of bytes that were put on the socket. |
| 466 | */ |
| 467 | SocketSentBytes CEMSocket::Send(uint32 maxNumberOfBytesToSend, uint32 minFragSize, bool onlyAllowedToSendControlPacket) |
| 468 | { |
| 469 | std::lock_guard<std::mutex> lock(m_sendLocker); |
| 470 | |
| 471 | //printf("* Attempt to send a packet on socket %p\n", this); |
| 472 | |
| 473 | if (byConnected == ES_DISCONNECTED) { |
| 474 | //printf("* Disconnected socket %p\n", this); |
| 475 | SocketSentBytes returnVal = { false, 0, 0 }; |
| 476 | return returnVal; |
| 477 | } else if (m_bBusy && onlyAllowedToSendControlPacket) { |
| 478 | //printf("* Busy socket %p\n", this); |
| 479 | SocketSentBytes returnVal = { true, 0, 0 }; |
| 480 | return returnVal; |
| 481 | } |
| 482 | |
| 483 | bool anErrorHasOccured = false; |
| 484 | uint32 sentStandardPacketBytesThisCall = 0; |
| 485 | uint32 sentControlPacketBytesThisCall = 0; |
| 486 | |
| 487 | if (byConnected == ES_CONNECTED && IsEncryptionLayerReady() && (!m_bBusy || onlyAllowedToSendControlPacket)) { |
| 488 | |
| 489 | //printf("* Internal attemptto send on %p\n", this); |
| 490 | |
| 491 | if(minFragSize < 1) { |
| 492 | minFragSize = 1; |
| 493 | } |
| 494 | |
| 495 | maxNumberOfBytesToSend = GetNextFragSize(maxNumberOfBytesToSend, minFragSize); |
| 496 | |
| 497 | uint64 now = ::GetTickCount64(); |
| 498 | bool bWasLongTimeSinceSend = (now - lastSent) > 1000; |
| 499 | |
| 500 | lastCalledSend = now; |
| 501 | |
| 502 | |
| 503 | while(sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall < maxNumberOfBytesToSend && anErrorHasOccured == false && // don't send more than allowed. Also, there should have been no error in earlier loop |
| 504 | (!m_control_queue.empty() || !m_standard_queue.empty() || sendbuffer != NULL) && // there must exist something to send |
| 505 | (onlyAllowedToSendControlPacket == false || // this means we are allowed to send both types of packets, so proceed |
| 506 | (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall > 0 && (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall) % minFragSize != 0) || |
| 507 | (sendbuffer == NULL && !m_control_queue.empty()) || // There's a control packet in queue, and we are not currently sending anything, so we will handle the control packet next |
| 508 | (sendbuffer != NULL && m_currentPacket_is_controlpacket == true) || // We are in the progress of sending a control packet. We are always allowed to send those |
| 509 | (sendbuffer != NULL && m_currentPacket_is_controlpacket == false && bWasLongTimeSinceSend && !m_control_queue.empty() && m_standard_queue.empty() && (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall) < minFragSize) // We have waited to long to clean the current packet (which may be a standard packet that is in the way). Proceed no matter what the value of onlyAllowedToSendControlPacket. |
| 510 | ) |
| 511 | ) { |
| 512 | |
| 513 | // If we are currently not in the progress of sending a packet, we will need to find the next one to send |
| 514 | if(sendbuffer == NULL) { |
| 515 | CPacket* curPacket = NULL; |
| 516 | if(!m_control_queue.empty()) { |
| 517 | // There's a control packet to send |
| 518 | m_currentPacket_is_controlpacket = true; |
| 519 | curPacket = m_control_queue.front(); |
| 520 | m_control_queue.pop_front(); |
| 521 | } else if(!m_standard_queue.empty() /*&& onlyAllowedToSendControlPacket == false*/) { |
| 522 | // There's a standard packet to send |
| 523 | m_currentPacket_is_controlpacket = false; |
| 524 | StandardPacketQueueEntry queueEntry = m_standard_queue.front(); |
nothing calls this directly
no test coverage detected