X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcpacket.c;h=a9ce5639d33f2546a140e67fe25a573f1592e5c3;hp=167d7d17a61fcae170a8cf4b8171344b9d6a447a;hb=c257b555225193e54d85daf541d29578b3c93882;hpb=f658940d02cf2fd893296b6a7825b42502573668 diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index 167d7d17..a9ce5639 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2003 Pekka Riikonen + Copyright (C) 1997 - 2005 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -56,8 +56,12 @@ int silc_packet_send(SilcSocketConnection sock, bool force_send) ret = silc_socket_write(sock); if (ret == -1) { - SILC_LOG_ERROR(("Error sending packet, dropped: %s", - strerror(errno))); + SILC_LOG_ERROR(("Error sending packet to %s:%d [%s], dropped: %s", + sock->hostname ? 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"), strerror(errno))); } if (ret != -2) return ret; @@ -323,10 +327,12 @@ bool silc_packet_receive_process(SilcSocketConnection sock, mac_len = silc_hmac_len(hmac); /* Parse the packets from the data */ + silc_socket_dup(sock); 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")); + silc_socket_free(sock); return TRUE; } @@ -349,6 +355,7 @@ bool silc_packet_receive_process(SilcSocketConnection sock, SILC_LOG_ERROR(("Received too short packet")); memset(header, 0, sizeof(header)); silc_buffer_clear(sock->inbuf); + silc_socket_free(sock); return FALSE; } @@ -357,6 +364,7 @@ bool silc_packet_receive_process(SilcSocketConnection sock, "(%d bytes)", paddedlen + mac_len - sock->inbuf->len)); SILC_SET_INBUF_PENDING(sock); memset(tmp, 0, sizeof(tmp)); + silc_socket_free(sock); return TRUE; } @@ -364,23 +372,27 @@ bool silc_packet_receive_process(SilcSocketConnection sock, if (!silc_packet_check_mac(hmac, sock->inbuf->data, paddedlen, sock->inbuf->data + paddedlen, sequence)) { SILC_LOG_WARNING(("Packet MAC check failed %s:%d " - "[%s type %d len %dB seq %d] [%s]", + "[%s type %d len %dB blen %dB seq %d] [%s] proto %d", sock->hostname, sock->port, silc_get_packet_name(header[3]), - header[3], paddedlen, sequence, + header[3], paddedlen, sock->inbuf->len, sequence, (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" : sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" : sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" : - "Router"))); + "Router"), + sock->protocol ? sock->protocol->protocol->type : -1)); memset(tmp, 0, sizeof(tmp)); silc_buffer_clear(sock->inbuf); + silc_socket_free(sock); return FALSE; } SILC_UNSET_INBUF_PENDING(sock); parse_ctx = silc_calloc(1, sizeof(*parse_ctx)); - if (!parse_ctx) + if (!parse_ctx) { + silc_socket_free(sock); return FALSE; + } parse_ctx->packet = silc_packet_context_alloc(); parse_ctx->packet->buffer = silc_buffer_alloc_size(paddedlen); parse_ctx->packet->type = (SilcPacketType)header[3]; @@ -431,6 +443,7 @@ bool silc_packet_receive_process(SilcSocketConnection sock, memset(tmp, 0, sizeof(tmp)); silc_packet_context_free(parse_ctx->packet); silc_free(parse_ctx); + silc_socket_free(sock); return FALSE; } } @@ -457,11 +470,21 @@ bool silc_packet_receive_process(SilcSocketConnection sock, memset(tmp, 0, sizeof(tmp)); } - if (cont == FALSE && sock->inbuf->len > 0) + /* Don't clear buffer if pending data is in the buffer */ + if (cont == FALSE && sock->inbuf->len > 0) { + silc_socket_free(sock); return TRUE; + } + + /* Don't clear buffer if QoS data exists in the buffer */ + if (sock->qos && sock->qos->data_len > 0) { + silc_socket_free(sock); + return TRUE; + } SILC_LOG_DEBUG(("Clearing inbound buffer")); silc_buffer_clear(sock->inbuf); + silc_socket_free(sock); return TRUE; }