Integer type name change.
[silc.git] / lib / silccore / silcpacket.c
index 7674a0302fa836b78a5bf1a4b750145db5491043..7f72922b5d6c4aac3de4ecbde37d0dfaa933c16e 100644 (file)
@@ -56,7 +56,8 @@ int silc_packet_send(SilcSocketConnection sock, bool force_send)
     ret = silc_socket_write(sock);
 
     if (ret == -1) {
-      SILC_LOG_ERROR(("Error sending packet, dropped"));
+      SILC_LOG_ERROR(("Error sending packet, dropped: %s", 
+                      strerror(errno)));
     }
     if (ret != -2)
       return ret;
@@ -76,11 +77,11 @@ int silc_packet_send(SilcSocketConnection sock, bool force_send)
    other process of HMAC computing and encryption is needed this function
    cannot be used. */
 
-void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, uint32 sequence,
-                        SilcBuffer buffer, uint32 len)
+void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, SilcUInt32 sequence,
+                        SilcBuffer buffer, SilcUInt32 len)
 {
   unsigned char mac[32];
-  uint32 mac_len;
+  SilcUInt32 mac_len;
 
   /* Compute HMAC. This assumes that HMAC is created from the entire
      data area thus this uses the length found in buffer, not the length
@@ -187,7 +188,8 @@ void silc_packet_assemble(SilcPacketContext *ctx, SilcCipher cipher)
 
   /* Get random padding */
 #if 1
-  for (i = 0; i < ctx->padlen; i++) tmppad[i] = silc_rng_global_get_byte();
+  for (i = 0; i < ctx->padlen; i++) tmppad[i] = 
+                                     silc_rng_global_get_byte_fast();
 #else
   /* XXX: For testing - to be removed */
   memset(tmppad, 65, sizeof(tmppad));
@@ -222,9 +224,9 @@ void silc_packet_assemble(SilcPacketContext *ctx, SilcCipher cipher)
    outgoing buffer in SilcSocketConnection object. */
 
 void silc_packet_send_prepare(SilcSocketConnection sock,
-                             uint32 header_len,
-                             uint32 padlen,
-                             uint32 data_len)
+                             SilcUInt32 header_len,
+                             SilcUInt32 padlen,
+                             SilcUInt32 data_len)
 {
   int totlen, oldlen;
 
@@ -282,7 +284,7 @@ void silc_packet_send_prepare(SilcSocketConnection sock,
 ******************************************************************************/
 
 static int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac, 
-                              uint32 sequence, SilcBuffer buffer, 
+                              SilcUInt32 sequence, SilcBuffer buffer, 
                               bool normal);
 
 /* Receives packet from network and reads the data into connection's
@@ -322,25 +324,34 @@ int silc_packet_receive(SilcSocketConnection sock)
    SilcPacketParserContext will indicate also whether the received
    packet was normal or special packet. */
 
-void silc_packet_receive_process(SilcSocketConnection sock,
+bool silc_packet_receive_process(SilcSocketConnection sock,
                                 bool local_is_router,
                                 SilcCipher cipher, SilcHmac hmac,
-                                uint32 sequence,
+                                SilcUInt32 sequence,
                                 SilcPacketParserCallback parser,
                                 void *parser_context)
 {
   SilcPacketParserContext *parse_ctx;
   int packetlen, paddedlen, mac_len = 0;
-  int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
+  bool cont = TRUE;
+
+  /* Do not process for disconnected connection */
+  if (SILC_IS_DISCONNECTED(sock))
+    return TRUE;
 
   if (sock->inbuf->len < SILC_PACKET_MIN_HEADER_LEN)
-    return;
+    return TRUE;
 
   if (hmac)
     mac_len = silc_hmac_len(hmac);
 
   /* Parse the packets from the data */
-  while (sock->inbuf->len > 0) {
+  while (sock->inbuf->len > 0 && cont) {
+
+    if (sock->inbuf->len < SILC_PACKET_MIN_HEADER_LEN) {
+      SILC_LOG_DEBUG(("Partial packet in queue, waiting for the rest"));
+      return TRUE;
+    }
 
     /* Decrypt first 16 bytes of the packet */
     if (!SILC_IS_INBUF_PENDING(sock) && cipher)
@@ -354,20 +365,21 @@ void silc_packet_receive_process(SilcSocketConnection sock,
     if (packetlen < SILC_PACKET_MIN_LEN) {
       SILC_LOG_DEBUG(("Received invalid packet, dropped"));
       silc_buffer_clear(sock->inbuf);
-      return;
+      return FALSE;
     }
 
     if (sock->inbuf->len < paddedlen + mac_len) {
       SILC_LOG_DEBUG(("Received partial packet, waiting for the rest"
                      "(%d < %d)", sock->inbuf->len, paddedlen + mac_len));
       SILC_SET_INBUF_PENDING(sock);
-      return;
+      return TRUE;
     }
 
     SILC_UNSET_INBUF_PENDING(sock);
     parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
     parse_ctx->packet = silc_packet_context_alloc();
     parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
+    parse_ctx->packet->type = sock->inbuf->data[3];
     parse_ctx->packet->padlen = sock->inbuf->data[4];
     parse_ctx->packet->sequence = sequence++;
     parse_ctx->sock = sock;
@@ -379,7 +391,8 @@ void silc_packet_receive_process(SilcSocketConnection sock,
                    paddedlen + mac_len);
 
     SILC_LOG_HEXDUMP(("Incoming packet (%d) (%dB decrypted), len %d", 
-                     sequence - 1, block_len, paddedlen + mac_len),
+                     sequence - 1, SILC_PACKET_MIN_HEADER_LEN, 
+                     paddedlen + mac_len),
                     sock->inbuf->data, paddedlen + mac_len);
 
     /* Check whether this is normal or special packet */
@@ -401,32 +414,43 @@ void silc_packet_receive_process(SilcSocketConnection sock,
 
     /* Decrypt rest of the packet */
     if (cipher)
-      silc_packet_decrypt(cipher, hmac, parse_ctx->packet->sequence, 
-                         parse_ctx->packet->buffer, parse_ctx->normal);
-
-    /* Call the parser */
-    if (parser)
-      (*parser)(parse_ctx, parser_context);
+      if (silc_packet_decrypt(cipher, hmac, parse_ctx->packet->sequence, 
+                             parse_ctx->packet->buffer, 
+                             parse_ctx->normal) == -1) {
+       SILC_LOG_WARNING(("Packet decryption failed %s:%d [%s]", 
+                         sock->hostname, sock->port,
+                         (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
+                          sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
+                          sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
+                          "Router")));
+      }
 
     /* Pull the packet from inbuf thus we'll get the next one
        in the inbuf. */
     silc_buffer_pull(sock->inbuf, paddedlen + mac_len);
+
+    /* Call the parser */
+    cont = (*parser)(parse_ctx, parser_context);
   }
 
+  if (cont == FALSE && sock->inbuf->len > 0)
+    return TRUE;
+
   SILC_LOG_DEBUG(("Clearing inbound buffer"));
   silc_buffer_clear(sock->inbuf);
+  return TRUE;
 }
 
 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
    after packet has been totally decrypted and parsed. */
 
 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer,
-                                uint32 sequence)
+                                SilcUInt32 sequence)
 {
   /* Check MAC */
   if (hmac) {
     unsigned char mac[32], psn[4];
-    uint32 mac_len;
+    SilcUInt32 mac_len;
     
     SILC_LOG_DEBUG(("Verifying MAC"));
 
@@ -440,11 +464,8 @@ static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer,
     silc_hmac_final(hmac, mac, &mac_len);
 
     /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
-    if (memcmp(mac, buffer->tail, mac_len)) {
+    if (memcmp(buffer->tail, mac, mac_len)) {
       SILC_LOG_ERROR(("MAC failed"));
-
-      /* XXX Remove */
-      assert(FALSE);
       return FALSE;
     }
     
@@ -502,7 +523,7 @@ static int silc_packet_decrypt_rest_special(SilcCipher cipher,
 {
   /* Decrypt rest of the header plus padding */
   if (cipher) {
-    uint16 len;
+    SilcUInt16 len;
 
     /* Pull MAC from packet before decryption */
     if (hmac) {
@@ -518,8 +539,8 @@ static int silc_packet_decrypt_rest_special(SilcCipher cipher,
 
     /* padding length + src id len + dst id len + header length - 16
        bytes already decrypted, gives the rest of the encrypted packet */
-    len = (((uint8)buffer->data[4] + (uint8)buffer->data[6] + 
-          (uint8)buffer->data[7] + SILC_PACKET_HEADER_LEN) -
+    len = (((SilcUInt8)buffer->data[4] + (SilcUInt8)buffer->data[6] + 
+          (SilcUInt8)buffer->data[7] + SILC_PACKET_HEADER_LEN) -
           SILC_PACKET_MIN_HEADER_LEN);
 
     silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN);
@@ -552,7 +573,7 @@ static int silc_packet_decrypt_rest_special(SilcCipher cipher,
    is special and requires special procesing. */
 
 static int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
-                              uint32 sequence, SilcBuffer buffer, 
+                              SilcUInt32 sequence, SilcBuffer buffer, 
                               bool normal)
 {
   /* If the packet type is not any special type lets decrypt rest
@@ -590,7 +611,7 @@ static int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
 SilcPacketType silc_packet_parse(SilcPacketContext *ctx, SilcCipher cipher)
 {
   SilcBuffer buffer = ctx->buffer;
-  uint8 tmp;
+  SilcUInt8 tmp;
   int len, ret;
 
   SILC_LOG_DEBUG(("Parsing incoming packet"));
@@ -658,7 +679,7 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx,
                                         SilcCipher cipher)
 {
   SilcBuffer buffer = ctx->buffer;
-  uint8 tmp;
+  SilcUInt8 tmp;
   int len, ret;
 
   SILC_LOG_DEBUG(("Parsing incoming packet"));