Beispiel #1
0
static void handle_server_audio(ENetPacket* packet) {
	enet_uint32 src, len;
	svc_network_packet_t np;

	/* ignore audio when locally muted */
	if (client.deafen) { /* FIXME: no lock, as deafen is only access from this thread (for now) */
		return;
	}

	/* decode header */
	src = ENET_NET_TO_HOST_32(*(enet_uint32*)(packet->data + 0));
	len = ENET_NET_TO_HOST_32(*(enet_uint32*)(packet->data + 4));
	if (src >= client.peers_size) {
		fprintf(stderr, "Invalid source %i in audio packet.\n", src);
		return;
	}

	/* make an audio packet */
	np.data = packet->data + 10;
	np.data_len = len - 2;
	np.time = ENET_NET_TO_HOST_16(*(enet_uint16*)(packet->data + 8));

	/* send audio to SVC */
	svc_packet_recieve(&np, client.peers[src].peer);
}
Beispiel #2
0
static void
enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
    if (command -> header.commandLength < sizeof (ENetProtocolBandwidthLimit))
      return;

    peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
    peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
}
Beispiel #3
0
static void
enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
    if (command -> header.commandLength < sizeof (ENetProtocolThrottleConfigure))
      return;

    peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval);
    peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration);
    peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration);
}
Beispiel #4
0
uint32_t MessageIn::readInt32()
{
    uint32_t value = 0;
    if (mPos + 4 <= mLength)
    {
        uint32_t t;
        memcpy(&t, mData + mPos, 4);
        value = ENET_NET_TO_HOST_32(t);
    }
    mPos += 4;
    return value;
}
Beispiel #5
0
static void
enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
{
    enet_uint16 mtu;
    enet_uint32 windowSize;

    if (command -> header.commandLength < sizeof (ENetProtocolVerifyConnect) ||
        peer -> state != ENET_PEER_STATE_CONNECTING)
      return;

    if (ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount) != peer -> channelCount ||
        ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval ||
        ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration ||
        ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration)
    {
        peer -> state = ENET_PEER_STATE_ZOMBIE;

        return;
    }

    peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID);

    mtu = ENET_NET_TO_HOST_16 (command -> verifyConnect.mtu);

    if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
      mtu = ENET_PROTOCOL_MINIMUM_MTU;
    else
    if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
      mtu = ENET_PROTOCOL_MAXIMUM_MTU;

    if (mtu < peer -> mtu)
      peer -> mtu = mtu;

    windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize);

    if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
      windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;

    if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
      windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;

    if (windowSize < peer -> windowSize)
      peer -> windowSize = windowSize;

    peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth);
    peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth);

    host -> recalculateBandwidthLimits = 1;

    peer -> state = ENET_PEER_STATE_CONNECTED;

    event -> type = ENET_EVENT_TYPE_CONNECT;
    event -> peer = peer;
}
Beispiel #6
0
static void
enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
    if (command -> header.commandLength < sizeof (ENetProtocolBandwidthLimit))
      return;

    peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
    peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);

    if (peer -> incomingBandwidth == 0 &&
        host -> outgoingBandwidth == 0)
      peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
    else
      peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) /
                             ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;

    if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
      peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
    else
    if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
      peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
}
Beispiel #7
0
int MessageIn::readInt32()
{
    int value = -1;
    if (mPos + 4 <= mLength)
    {
        uint32_t t;
        memcpy(&t, mData + mPos, 4);
        value = ENET_NET_TO_HOST_32(t);
    }
    else LOG_DEBUG("Unable to read 4 bytes in " << this->getId() << "!");
    mPos += 4;
    return value;
}
Beispiel #8
0
/** Queues a packet to be sent.
    @param peer destination for the packet
    @param channelID channel on which to send
    @param packet packet to send
    @retval 0 on success
    @retval < 0 on failure
*/
int
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
{
   ENetChannel * channel = & peer -> channels [channelID];
   ENetProtocol command;
   size_t fragmentLength;

   if (peer -> state != ENET_PEER_STATE_CONNECTED ||
       channelID >= peer -> channelCount)
     return -1;

   fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);

   if (packet -> dataLength > fragmentLength)
   {
      enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
      enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
             fragmentNumber,
             fragmentOffset;
      ENetList fragments;
      ENetOutgoingCommand * fragment;

      enet_list_clear (& fragments);

      for (fragmentNumber = 0,
             fragmentOffset = 0;
           fragmentOffset < packet -> dataLength;
           ++ fragmentNumber,
             fragmentOffset += fragmentLength)
      {
         if (packet -> dataLength - fragmentOffset < fragmentLength)
           fragmentLength = packet -> dataLength - fragmentOffset;

         fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
         if (fragment == NULL)
         {
            while (! enet_list_empty (& fragments))
            {
               fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
               
               enet_free (fragment);
            }
            
            return -1;
         }
         
         fragment -> fragmentOffset = fragmentOffset;
         fragment -> fragmentLength = fragmentLength;
         fragment -> packet = packet;
         fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
         fragment -> command.header.channelID = channelID;
         fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
         fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
         fragment -> command.sendFragment.fragmentCount = fragmentCount;
         fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
         fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
         fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
        
         enet_list_insert (enet_list_end (& fragments), fragment);
      }

      packet -> referenceCount += fragmentNumber;

      while (! enet_list_empty (& fragments))
      {
         fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
 
         enet_peer_setup_outgoing_command (peer, fragment);
      }

      return 0;
   }

   command.header.channelID = channelID;

   if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
   }
   else
   if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
      command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
      command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
   }
   else 
   if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
   }
   else
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
      command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
      command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
   }

   if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL)
     return -1;

   return 0;
}
Beispiel #9
0
ENetIncomingCommand *
enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
{
    ENetChannel * channel = & peer -> channels [command -> header.channelID];
    enet_uint32 unreliableSequenceNumber = 0;
    ENetIncomingCommand * incomingCommand;
    ENetListIterator currentCommand;

    switch (command -> header.command)
    {
    case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
    case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
       for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
            currentCommand != enet_list_end (& channel -> incomingReliableCommands);
            currentCommand = enet_list_previous (currentCommand))
       {
          incomingCommand = (ENetIncomingCommand *) currentCommand;

          if (incomingCommand -> reliableSequenceNumber <= command -> header.reliableSequenceNumber)
          {
             if (incomingCommand -> reliableSequenceNumber < command -> header.reliableSequenceNumber)
               break;

             goto freePacket;
          }
       }
       break;

    case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
       unreliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> sendUnreliable.unreliableSequenceNumber);

       if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
         goto freePacket;

       if (unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber)
         goto freePacket;

       for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
            currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
            currentCommand = enet_list_previous (currentCommand))
       {
          incomingCommand = (ENetIncomingCommand *) currentCommand;

          if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
          {
             if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
               break;

             goto freePacket;
          }
       }
       break;

    case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
       currentCommand = enet_list_end (& channel -> incomingUnreliableCommands);
       break;

    default:
       goto freePacket;
    }

    incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));

    incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
    incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber;
    incomingCommand -> command = * command;
    incomingCommand -> fragmentCount = fragmentCount;
    incomingCommand -> fragmentsRemaining = fragmentCount;
    incomingCommand -> packet = packet;
    incomingCommand -> fragments = NULL;

    if (fragmentCount > 0)
    {
       incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
       memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32));
    }

    if (packet != NULL)
      ++ packet -> referenceCount;

    enet_list_insert (enet_list_next (currentCommand), incomingCommand);

    return incomingCommand;

freePacket:
    if (packet != NULL)
    {
       if (packet -> referenceCount == 0)
         enet_packet_destroy (packet);
    }

    return NULL;
}
Beispiel #10
0
/** Queues a packet to be sent.
    @param peer destination for the packet
    @param channelID channel on which to send
    @param packet packet to send
    @retval 0 on success
    @retval < 0 on failure
*/
int
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
{
   ENetChannel * channel = & peer -> channels [channelID];
   ENetProtocol command;
   size_t fragmentLength;

   if (peer -> state != ENET_PEER_STATE_CONNECTED ||
       channelID >= peer -> channelCount)
     return -1;

   fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);

   if (packet -> dataLength > fragmentLength)
   {
      enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
             startSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingReliableSequenceNumber + 1),
             fragmentNumber,
             fragmentOffset;

      packet -> flags = ENET_PACKET_FLAG_RELIABLE;

      for (fragmentNumber = 0,
             fragmentOffset = 0;
           fragmentOffset < packet -> dataLength;
           ++ fragmentNumber,
             fragmentOffset += fragmentLength)
      {
         command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT;
         command.header.channelID = channelID;
         command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
         command.header.commandLength = sizeof (ENetProtocolSendFragment);
         command.sendFragment.startSequenceNumber = startSequenceNumber;
         command.sendFragment.fragmentCount = fragmentCount;
         command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
         command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
         command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);

         if (packet -> dataLength - fragmentOffset < fragmentLength)
           fragmentLength = packet -> dataLength - fragmentOffset;

         enet_peer_queue_outgoing_command (peer, & command, packet, fragmentOffset, fragmentLength);
      }

      return 0;
   }

   command.header.channelID = channelID;

   if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE;
      command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
      command.header.commandLength = sizeof (ENetProtocolSendReliable);
   }
   else
   if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED;
      command.header.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED;
      command.header.commandLength = sizeof (ENetProtocolSendUnsequenced);
      command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_32 (peer -> outgoingUnsequencedGroup + 1);
   }
   else
   {
      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
      command.header.flags = 0;
      command.header.commandLength = sizeof (ENetProtocolSendUnreliable);
      command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingUnreliableSequenceNumber + 1);
   }

   enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength);

   return 0;
}
Beispiel #11
0
static int
enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
{
    ENetProtocolHeader * header;
    ENetProtocol * command;
    ENetPeer * peer;
    enet_uint8 * currentData;
    size_t commandCount;

    if (host -> receivedDataLength < sizeof (ENetProtocolHeader))
      return 0;

    header = (ENetProtocolHeader *) host -> receivedData;

    header -> peerID = ENET_NET_TO_HOST_16 (header -> peerID);
    header -> sentTime = ENET_NET_TO_HOST_32 (header -> sentTime);

    if (header -> peerID == 0xFFFF)
      peer = NULL;
    else
    if (header -> peerID >= host -> peerCount)
      return 0;
    else
    {
       peer = & host -> peers [header -> peerID];

       if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
           peer -> state == ENET_PEER_STATE_ZOMBIE ||
           host -> receivedAddress.host != peer -> address.host ||
           header -> challenge != peer -> challenge)
         return 0;
       else
         peer -> address.port = host -> receivedAddress.port;
    }

    if (peer != NULL)
      peer -> incomingDataTotal += host -> receivedDataLength;

    commandCount = header -> commandCount;
    currentData = host -> receivedData + sizeof (ENetProtocolHeader);

    while (commandCount > 0 &&
           currentData < & host -> receivedData [host -> receivedDataLength])
    {
       command = (ENetProtocol *) currentData;

       if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength])
         return 0;

       command -> header.commandLength = ENET_NET_TO_HOST_32 (command -> header.commandLength);

       if (currentData + command -> header.commandLength > & host -> receivedData [host -> receivedDataLength])
         return 0;

       -- commandCount;
       currentData += command -> header.commandLength;

       if (peer == NULL)
       {
          if (command -> header.command != ENET_PROTOCOL_COMMAND_CONNECT)
            return 0;
       }

       command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> header.reliableSequenceNumber);

       switch (command -> header.command)
       {
       case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE:
          enet_protocol_handle_acknowledge (host, event, peer, command);

          break;

       case ENET_PROTOCOL_COMMAND_CONNECT:
          peer = enet_protocol_handle_connect (host, header, command);

          break;

       case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT:
          enet_protocol_handle_verify_connect (host, event, peer, command);

          break;

       case ENET_PROTOCOL_COMMAND_DISCONNECT:
          enet_protocol_handle_disconnect (host, peer, command);

          break;

       case ENET_PROTOCOL_COMMAND_PING:
          enet_protocol_handle_ping (host, peer, command);

          break;

       case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
          enet_protocol_handle_send_reliable (host, peer, command);

          break;

       case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
          enet_protocol_handle_send_unreliable (host, peer, command);

          break;

       case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
          enet_protocol_handle_send_fragment (host, peer, command);

          break;

       case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT:
          enet_protocol_handle_bandwidth_limit (host, peer, command);

          break;

       case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE:
          enet_protocol_handle_throttle_configure (host, peer, command);

          break;

       default:
          break;
       }

       if (peer != NULL &&
           (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) != 0)
       {
           switch (peer -> state)
           {
           case ENET_PEER_STATE_DISCONNECTING:
              break;

           case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
              if (command -> header.command != ENET_PROTOCOL_COMMAND_DISCONNECT)
                break;

           default:
              enet_peer_queue_acknowledgement (peer, command, header -> sentTime);

              break;
           }
       }
    }

    if (event -> type != ENET_EVENT_TYPE_NONE)
      return 1;

    return 0;
}
Beispiel #12
0
static int
enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
{
    enet_uint32 roundTripTime,
           receivedSentTime,
           receivedReliableSequenceNumber;
    ENetProtocolCommand commandNumber;

    if (command -> header.commandLength < sizeof (ENetProtocolAcknowledge))
      return 0;

    receivedSentTime = ENET_NET_TO_HOST_32 (command -> acknowledge.receivedSentTime);

    if (ENET_TIME_LESS (timeCurrent, receivedSentTime))
      return 0;

    peer -> lastReceiveTime = timeCurrent;

    roundTripTime = ENET_TIME_DIFFERENCE (timeCurrent, receivedSentTime);

    enet_peer_throttle (peer, roundTripTime);

    peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;

    if (roundTripTime >= peer -> roundTripTime)
    {
       peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
       peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
    }
    else
    {
       peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
       peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
    }

    if (peer -> roundTripTime < peer -> lowestRoundTripTime)
      peer -> lowestRoundTripTime = peer -> roundTripTime;

    if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
      peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;

    if (peer -> packetThrottleEpoch == 0 ||
        ENET_TIME_DIFFERENCE(timeCurrent, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
    {
        peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
        peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance;
        peer -> lowestRoundTripTime = peer -> roundTripTime;
        peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
        peer -> packetThrottleEpoch = timeCurrent;
    }

    receivedReliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> acknowledge.receivedReliableSequenceNumber);

    commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);

    switch (peer -> state)
    {
    case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
       if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT)
         return 0;

       host -> recalculateBandwidthLimits = 1;

       peer -> state = ENET_PEER_STATE_CONNECTED;

       event -> type = ENET_EVENT_TYPE_CONNECT;
       event -> peer = peer;

       return 1;

    case ENET_PEER_STATE_DISCONNECTING:
       if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT)
         return 0;

       host -> recalculateBandwidthLimits = 1;

       event -> type = ENET_EVENT_TYPE_DISCONNECT;
       event -> peer = peer;

       enet_peer_reset (peer);

       return 1;

    default:
       break;
    }

    return 0;
}
Beispiel #13
0
static void
enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
    enet_uint32 fragmentNumber,
           fragmentCount,
           fragmentOffset,
           fragmentLength,
           startSequenceNumber,
           totalLength;
    ENetChannel * channel;
    ENetListIterator currentCommand;
    ENetIncomingCommand * startCommand;

    if (command -> header.commandLength <= sizeof (ENetProtocolSendFragment) ||
        command -> header.channelID >= peer -> channelCount ||
        peer -> state != ENET_PEER_STATE_CONNECTED)
      return;

    startSequenceNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.startSequenceNumber);
    fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
    fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
    fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
    totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
    fragmentLength = command -> header.commandLength - sizeof (ENetProtocolSendFragment);

    if (fragmentOffset >= totalLength ||
        fragmentOffset + fragmentLength > totalLength ||
        fragmentNumber >= fragmentCount)
      return;

    channel = & peer -> channels [command -> header.channelID];

    if (startSequenceNumber <= channel -> incomingReliableSequenceNumber)
      return;

    for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
         currentCommand != enet_list_end (& channel -> incomingReliableCommands);
         currentCommand = enet_list_previous (currentCommand))
    {
       startCommand = (ENetIncomingCommand *) currentCommand;

       if (startCommand -> command.header.command == ENET_PROTOCOL_COMMAND_SEND_FRAGMENT &&
           startCommand -> command.sendFragment.startSequenceNumber == startSequenceNumber)
         break;
    }

    if (currentCommand == enet_list_end (& channel -> incomingReliableCommands))
    {
       ENetProtocol hostCommand = * command;

       hostCommand.sendFragment.startSequenceNumber = startSequenceNumber;
       hostCommand.sendFragment.fragmentNumber = fragmentNumber;
       hostCommand.sendFragment.fragmentCount = fragmentCount;
       hostCommand.sendFragment.fragmentOffset = fragmentOffset;
       hostCommand.sendFragment.totalLength = totalLength;

       startCommand = enet_peer_queue_incoming_command (peer,
                                                        & hostCommand,
                                                        enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE),
                                                        fragmentCount);
    }
    else
    if (totalLength != startCommand -> packet -> dataLength ||
        fragmentCount != startCommand -> fragmentCount)
      return;

    if ((startCommand -> fragments [fragmentNumber / 32] & (1 << fragmentNumber)) == 0)
      -- startCommand -> fragmentsRemaining;

    startCommand -> fragments [fragmentNumber / 32] |= (1 << fragmentNumber);

    if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength)
      fragmentLength = startCommand -> packet -> dataLength - fragmentOffset;

    memcpy (startCommand -> packet -> data + fragmentOffset,
            (enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
            fragmentLength);
}
Beispiel #14
0
static ENetPeer *
enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header, const ENetProtocol * command)
{
    enet_uint16 mtu;
    enet_uint32 windowSize;
    ENetChannel * channel;
    size_t channelCount;
    ENetPeer * currentPeer;
    ENetProtocol verifyCommand;

    if (command -> header.commandLength < sizeof (ENetProtocolConnect))
      return NULL;

    channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount);

    if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT ||
        channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
      return NULL;

    for (currentPeer = host -> peers;
         currentPeer < & host -> peers [host -> peerCount];
         ++ currentPeer)
    {
        if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
            currentPeer -> address.host == host -> receivedAddress.host &&
            currentPeer -> address.port == host -> receivedAddress.port &&
            currentPeer -> challenge == header -> challenge)
          return NULL;
    }

    for (currentPeer = host -> peers;
         currentPeer < & host -> peers [host -> peerCount];
         ++ currentPeer)
    {
        if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
          break;
    }

    if (currentPeer >= & host -> peers [host -> peerCount])
      return NULL;

    currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
    currentPeer -> challenge = header -> challenge;
    currentPeer -> address = host -> receivedAddress;
    currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
    currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
    currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
    currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval);
    currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration);
    currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration);
    currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
    currentPeer -> channelCount = channelCount;

    for (channel = currentPeer -> channels;
         channel < & currentPeer -> channels [channelCount];
         ++ channel)
    {
        channel -> outgoingReliableSequenceNumber = 0;
        channel -> outgoingUnreliableSequenceNumber = 0;
        channel -> incomingReliableSequenceNumber = 0;
        channel -> incomingUnreliableSequenceNumber = 0;

        enet_list_clear (& channel -> incomingReliableCommands);
        enet_list_clear (& channel -> incomingUnreliableCommands);
    }

    mtu = ENET_NET_TO_HOST_16 (command -> connect.mtu);

    if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
      mtu = ENET_PROTOCOL_MINIMUM_MTU;
    else
    if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
      mtu = ENET_PROTOCOL_MAXIMUM_MTU;

    currentPeer -> mtu = mtu;

    if (host -> outgoingBandwidth == 0 &&
        currentPeer -> incomingBandwidth == 0)
      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
    else
      currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
                                    ENET_PEER_WINDOW_SIZE_SCALE) *
                                      ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;

    if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
      currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
    else
    if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;

    if (host -> incomingBandwidth == 0)
      windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
    else
      windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) *
                     ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;

    if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize))
      windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize);

    if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
      windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
    else
    if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
      windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;

    verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT;
    verifyCommand.header.channelID = 0xFF;
    verifyCommand.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
    verifyCommand.header.commandLength = sizeof (ENetProtocolVerifyConnect);
    verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
    verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
    verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize);
    verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
    verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
    verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
    verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
    verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
    verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);

    enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0);

    return currentPeer;
}
Beispiel #15
0
uint32_t getip(uint32_t ip)
{
    if (!geoip) return 0u;
    ip = ENET_NET_TO_HOST_32(ip);
    return getip(GeoIP_country_code_by_ipnum(geoip, ip));
}