5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 * Created: Fri Jul 25 18:52:14 1997
24 #include "silcincludes.h"
26 /******************************************************************************
28 Packet Sending Routines
30 ******************************************************************************/
32 /* Actually sends the packet. This flushes the connections outgoing data
33 buffer. If data is sent directly to the network this returns the bytes
34 written, if error occured this returns -1 and if the data could not
35 be written directly to the network at this time this returns -2, in
36 which case the data should be queued by the caller and sent at some
37 later time. If `force_send' is TRUE this attempts to write the data
38 directly to the network, if FALSE, this returns -2. */
40 int silc_packet_send(SilcSocketConnection sock, bool force_send)
42 SILC_LOG_DEBUG(("Sending packet to %s:%d [%s]", sock->hostname,
44 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
45 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
46 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
49 /* Send now if forced to do so */
50 if (force_send == TRUE) {
53 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
55 /* Write to network */
56 ret = silc_socket_write(sock);
59 SILC_LOG_ERROR(("Error sending packet, dropped: %s",
65 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
68 SILC_LOG_DEBUG(("Packet in queue"));
73 /* Encrypts a packet. This also creates HMAC of the packet before
74 encryption and adds the HMAC at the end of the buffer. This assumes
75 that there is enough free space at the end of the buffer to add the
76 computed HMAC. This is the normal way of encrypting packets, if some
77 other process of HMAC computing and encryption is needed this function
80 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, SilcUInt32 sequence,
81 SilcBuffer buffer, SilcUInt32 len)
84 /* Encrypt the data area of the packet. */
86 SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d",
87 silc_cipher_get_name(cipher), len));
88 silc_cipher_encrypt(cipher, buffer->data, buffer->data, len,
89 silc_cipher_get_iv(cipher));
92 /* Compute HMAC. This assumes that MAC is computed from the entire
93 data area thus this uses the length found in buffer, not the length
96 unsigned char mac[32], psn[4];
100 SILC_PUT32_MSB(sequence, psn);
101 silc_hmac_update(hmac, psn, 4);
102 silc_hmac_update(hmac, buffer->data, buffer->len);
103 silc_hmac_final(hmac, mac, &mac_len);
105 /* Put MAC and pull the it into the visible data area in the buffer */
106 silc_buffer_put_tail(buffer, mac, mac_len);
107 silc_buffer_pull_tail(buffer, mac_len);
111 /* Assembles a new packet to be ready for send out. */
113 bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
114 SilcCipher cipher, SilcHmac hmac,
115 SilcSocketConnection sock,
116 const unsigned char *data, SilcUInt32 data_len,
117 const SilcBuffer assembled_packet)
119 unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
120 int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
123 SILC_LOG_DEBUG(("Assembling outgoing packet"));
125 /* Calculate the packet's length and padding length if upper layer
126 didn't already do it. */
128 /* Get the true length of the packet. This is saved as payload length
129 into the packet header. This does not include the length of the
131 if (!packet->truelen) {
132 data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
133 packet->src_id_len + packet->dst_id_len);
134 packet->truelen = data_len + SILC_PACKET_HEADER_LEN +
135 packet->src_id_len + packet->dst_id_len;
138 /* Calculate the length of the padding. The padding is calculated from
139 the data that will be encrypted. */
140 if (!packet->padlen) {
141 if (packet->long_pad)
142 SILC_PACKET_PADLEN_MAX(packet->truelen, block_len, packet->padlen);
144 SILC_PACKET_PADLEN(packet->truelen, block_len, packet->padlen);
147 /* Now prepare the outgoing data buffer for packet sending and start
148 assembling the packet. */
150 /* Return pointer to the assembled packet */
151 if (!silc_packet_send_prepare(sock, packet->truelen - data_len,
152 packet->padlen, data_len, hmac,
156 /* Get random padding */
158 for (i = 0; i < packet->padlen; i++) tmppad[i] =
159 silc_rng_get_byte_fast(rng);
161 for (i = 0; i < packet->padlen; i++) tmppad[i] =
162 silc_rng_global_get_byte_fast();
164 /* Create the packet. This creates the SILC header, adds padding, and
165 the actual packet data. */
167 silc_buffer_format(assembled_packet,
168 SILC_STR_UI_SHORT(packet->truelen),
169 SILC_STR_UI_CHAR(packet->flags),
170 SILC_STR_UI_CHAR(packet->type),
171 SILC_STR_UI_CHAR(packet->padlen),
173 SILC_STR_UI_CHAR(packet->src_id_len),
174 SILC_STR_UI_CHAR(packet->dst_id_len),
175 SILC_STR_UI_CHAR(packet->src_id_type),
176 SILC_STR_UI_XNSTRING(packet->src_id,
178 SILC_STR_UI_CHAR(packet->dst_id_type),
179 SILC_STR_UI_XNSTRING(packet->dst_id,
181 SILC_STR_UI_XNSTRING(tmppad, packet->padlen),
182 SILC_STR_UI_XNSTRING(data, data_len),
187 SILC_LOG_HEXDUMP(("Assembled packet, len %d", assembled_packet->len),
188 assembled_packet->data, assembled_packet->len);
193 /* Prepare outgoing data buffer for packet sending. This moves the data
194 area so that new packet may be added into it. If needed this allocates
195 more space to the buffer. This handles directly the connection's
196 outgoing buffer in SilcSocketConnection object, and returns the
197 pointer to that buffer into the `packet'. */
199 bool silc_packet_send_prepare(SilcSocketConnection sock,
200 SilcUInt32 header_len,
204 const SilcBuffer packet)
207 unsigned char *oldptr;
208 int mac_len = hmac ? silc_hmac_len(hmac) : 0;
213 totlen = header_len + pad_len + data_len;
215 /* Prepare the outgoing buffer for packet sending. */
217 /* Allocate new buffer. This is done only once per connection. */
218 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
220 sock->outbuf = silc_buffer_alloc(totlen > SILC_PACKET_DEFAULT_SIZE ?
221 totlen : SILC_PACKET_DEFAULT_SIZE);
225 if (!SILC_IS_OUTBUF_PENDING(sock)) {
226 /* Buffer is free for use */
227 silc_buffer_clear(sock->outbuf);
231 /* Allocate more space if needed */
232 if ((sock->outbuf->end - sock->outbuf->tail) < (totlen + mac_len)) {
233 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
234 sock->outbuf = silc_buffer_realloc(sock->outbuf,
235 sock->outbuf->truelen + (totlen * 2));
240 /* Pull data area for the new packet, and return pointer to the start of
241 the data area and save the pointer in to the `packet'. */
242 oldptr = silc_buffer_pull_tail(sock->outbuf, totlen + mac_len);
243 silc_buffer_set(packet, oldptr, totlen + mac_len);
244 silc_buffer_push_tail(packet, mac_len);
249 /******************************************************************************
251 Packet Reception Routines
253 ******************************************************************************/
255 static int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
256 SilcUInt32 sequence, SilcBuffer buffer,
258 static bool silc_packet_check_mac(SilcHmac hmac,
259 const unsigned char *data,
261 const unsigned char *packet_mac,
262 SilcUInt32 sequence);
264 /* Receives packet from network and reads the data into connection's
265 incoming data buffer. If the data was read directly this returns the
266 read bytes, if error occured this returns -1, if the data could not
267 be read directly at this time this returns -2 in which case the data
268 should be read again at some later time, or If EOF occured this returns
271 int silc_packet_receive(SilcSocketConnection sock)
275 SILC_LOG_DEBUG(("Receiving packet from %s:%d [%s]", sock->hostname,
277 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
278 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
279 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
282 /* Read some data from connection */
283 ret = silc_socket_read(sock);
288 /* Processes and decrypts the incmoing data, and calls parser callback
289 for each received packet that will handle the actual packet parsing.
290 If more than one packet was received this calls the parser multiple
291 times. The parser callback will get context SilcPacketParserContext
292 that includes the packet and the `parser_context' sent to this
295 The `local_is_router' indicates whether the caller is router server
296 in which case the receiving process of a certain packet types may
297 be special. Normal server and client must set it to FALSE. The
298 SilcPacketParserContext will indicate also whether the received
299 packet was normal or special packet. */
301 bool silc_packet_receive_process(SilcSocketConnection sock,
302 bool local_is_router,
303 SilcCipher cipher, SilcHmac hmac,
305 SilcPacketParserCallback parser,
306 void *parser_context)
308 SilcPacketParserContext *parse_ctx;
309 int packetlen, paddedlen, mac_len = 0, ret, block_len;
311 unsigned char tmp[SILC_PACKET_MIN_HEADER_LEN], *header;
312 unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
314 /* Do not process for disconnected connection */
315 if (SILC_IS_DISCONNECTED(sock))
318 if (sock->inbuf->len < SILC_PACKET_MIN_HEADER_LEN)
322 mac_len = silc_hmac_len(hmac);
324 /* Parse the packets from the data */
325 while (sock->inbuf->len > 0 && cont) {
327 if (sock->inbuf->len < SILC_PACKET_MIN_HEADER_LEN) {
328 SILC_LOG_DEBUG(("Partial packet in queue, waiting for the rest"));
332 /* Decrypt first block of the packet to get the length field out */
334 block_len = silc_cipher_get_block_len(cipher);
335 memcpy(iv, silc_cipher_get_iv(cipher), block_len);
336 silc_cipher_decrypt(cipher, sock->inbuf->data, tmp, block_len, iv);
339 block_len = SILC_PACKET_MIN_HEADER_LEN;
340 header = sock->inbuf->data;
343 /* Get packet lenght and full packet length with padding */
344 SILC_PACKET_LENGTH(header, packetlen, paddedlen);
347 if (packetlen < SILC_PACKET_MIN_LEN) {
348 SILC_LOG_ERROR(("Received too short packet"));
349 memset(header, 0, sizeof(header));
350 silc_buffer_clear(sock->inbuf);
354 if (sock->inbuf->len < paddedlen + mac_len) {
355 SILC_LOG_DEBUG(("Received partial packet, waiting for the rest "
356 "(%d bytes)", paddedlen + mac_len - sock->inbuf->len));
357 SILC_SET_INBUF_PENDING(sock);
358 memset(tmp, 0, sizeof(tmp));
362 /* Check MAC of the packet */
363 if (!silc_packet_check_mac(hmac, sock->inbuf->data, paddedlen,
364 sock->inbuf->data + paddedlen, sequence)) {
365 SILC_LOG_WARNING(("Packet MAC check failed %s:%d [%s] [%s]",
366 sock->hostname, sock->port,
367 silc_get_packet_name(header[3]),
368 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
369 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
370 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
372 memset(tmp, 0, sizeof(tmp));
373 silc_buffer_clear(sock->inbuf);
377 SILC_UNSET_INBUF_PENDING(sock);
378 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
381 parse_ctx->packet = silc_packet_context_alloc();
382 parse_ctx->packet->buffer = silc_buffer_alloc_size(paddedlen);
383 parse_ctx->packet->type = header[3];
384 parse_ctx->packet->padlen = header[4];
385 parse_ctx->packet->sequence = sequence++;
386 parse_ctx->sock = sock;
387 parse_ctx->context = parser_context;
389 /* Check whether this is normal or special packet */
390 if (local_is_router) {
391 if (header[3] == SILC_PACKET_PRIVATE_MESSAGE &&
392 (header[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
393 parse_ctx->normal = FALSE;
394 else if (header[3] != SILC_PACKET_CHANNEL_MESSAGE ||
395 (header[3] == SILC_PACKET_CHANNEL_MESSAGE &&
396 sock->type == SILC_SOCKET_TYPE_ROUTER))
397 parse_ctx->normal = TRUE;
399 if (header[3] == SILC_PACKET_PRIVATE_MESSAGE &&
400 (header[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
401 parse_ctx->normal = FALSE;
402 else if (header[3] != SILC_PACKET_CHANNEL_MESSAGE)
403 parse_ctx->normal = TRUE;
406 SILC_LOG_HEXDUMP(("Incoming packet (%d) len %d",
407 sequence - 1, paddedlen + mac_len),
408 sock->inbuf->data, paddedlen + mac_len);
410 /* Put the decrypted part, and rest of the encrypted data, and decrypt */
411 silc_buffer_put(parse_ctx->packet->buffer, header, block_len);
412 silc_buffer_pull(parse_ctx->packet->buffer, block_len);
413 silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data + block_len,
414 paddedlen - block_len);
416 silc_cipher_set_iv(cipher, iv);
417 ret = silc_packet_decrypt(cipher, hmac, parse_ctx->packet->sequence,
418 parse_ctx->packet->buffer,
421 SILC_LOG_WARNING(("Packet decryption failed %s:%d [%s] [%s]",
422 sock->hostname, sock->port,
423 silc_get_packet_name(parse_ctx->packet->type),
424 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
425 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
426 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
428 memset(tmp, 0, sizeof(tmp));
429 silc_packet_context_free(parse_ctx->packet);
430 silc_free(parse_ctx);
434 silc_buffer_push(parse_ctx->packet->buffer, block_len);
436 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d",
437 parse_ctx->packet->buffer->len),
438 parse_ctx->packet->buffer->data,
439 parse_ctx->packet->buffer->len);
441 /* Pull the packet from inbuf thus we'll get the next one
443 silc_buffer_pull(sock->inbuf, paddedlen + mac_len);
445 /* Call the parser */
446 cont = (*parser)(parse_ctx, parser_context);
447 memset(tmp, 0, sizeof(tmp));
450 if (cont == FALSE && sock->inbuf->len > 0)
453 SILC_LOG_DEBUG(("Clearing inbound buffer"));
454 silc_buffer_clear(sock->inbuf);
458 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. */
460 static bool silc_packet_check_mac(SilcHmac hmac,
461 const unsigned char *data,
463 const unsigned char *packet_mac,
468 unsigned char mac[32], psn[4];
471 SILC_LOG_DEBUG(("Verifying MAC"));
473 /* Compute HMAC of packet */
474 silc_hmac_init(hmac);
475 SILC_PUT32_MSB(sequence, psn);
476 silc_hmac_update(hmac, psn, 4);
477 silc_hmac_update(hmac, data, data_len);
478 silc_hmac_final(hmac, mac, &mac_len);
480 /* Compare the MAC's */
481 if (memcmp(packet_mac, mac, mac_len)) {
482 SILC_LOG_ERROR(("MAC failed"));
486 SILC_LOG_DEBUG(("MAC is Ok"));
492 /* Decrypts SILC packet. Handles both normal and special packet decryption.
493 Return 0 when packet is normal and 1 when it it special, -1 on error. */
495 static int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
496 SilcUInt32 sequence, SilcBuffer buffer,
499 /* If the packet type is not any special type lets decrypt rest
500 of the packet here. */
501 if (normal == TRUE) {
503 /* Decrypt rest of the packet */
504 SILC_LOG_DEBUG(("Decrypting the packet"));
505 silc_cipher_decrypt(cipher, buffer->data, buffer->data, buffer->len,
506 silc_cipher_get_iv(cipher));
511 /* Decrypt rest of the header plus padding */
514 int block_len = silc_cipher_get_block_len(cipher);
516 SILC_LOG_DEBUG(("Decrypting the header"));
518 /* padding length + src id len + dst id len + header length - 16
519 bytes already decrypted, gives the rest of the encrypted packet */
520 silc_buffer_push(buffer, block_len);
521 len = (((SilcUInt8)buffer->data[4] + (SilcUInt8)buffer->data[6] +
522 (SilcUInt8)buffer->data[7] + SILC_PACKET_HEADER_LEN) -
525 if (len > buffer->len) {
526 SILC_LOG_ERROR(("Garbage in header of packet, bad packet length, "
530 silc_buffer_pull(buffer, block_len);
531 silc_cipher_decrypt(cipher, buffer->data, buffer->data, len,
532 silc_cipher_get_iv(cipher));
539 /* Parses the packet. This is called when a whole packet is ready to be
540 parsed. The buffer sent must be already decrypted before calling this
541 function. The len argument must be the true length of the packet. This
542 function returns the type of the packet. The data section of the
543 buffer is parsed, not head or tail sections. */
545 SilcPacketType silc_packet_parse(SilcPacketContext *ctx, SilcCipher cipher)
547 SilcBuffer buffer = ctx->buffer;
550 SilcUInt8 src_id_len, src_id_type, dst_id_len, dst_id_type, padlen;
552 SILC_LOG_DEBUG(("Parsing incoming packet"));
554 /* Check the length of the buffer */
555 if (buffer->len < SILC_PACKET_MIN_LEN) {
556 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
557 return SILC_PACKET_NONE;
560 /* Parse the buffer. This parses the SILC header of the packet. */
561 len = silc_buffer_unformat(buffer,
562 SILC_STR_UI_SHORT(&ctx->truelen),
563 SILC_STR_UI_CHAR(&ctx->flags),
564 SILC_STR_UI_CHAR(&ctx->type),
565 SILC_STR_UI_CHAR(&padlen),
566 SILC_STR_UI_CHAR(&tmp),
567 SILC_STR_UI_CHAR(&src_id_len),
568 SILC_STR_UI_CHAR(&dst_id_len),
569 SILC_STR_UI_CHAR(&src_id_type),
571 if (len == -1 || tmp != 0)
572 return SILC_PACKET_NONE;
574 if (src_id_len > SILC_PACKET_MAX_ID_LEN ||
575 dst_id_len > SILC_PACKET_MAX_ID_LEN) {
576 SILC_LOG_ERROR(("Bad ID lengths in packet (%d and %d)",
577 src_id_len, dst_id_len));
578 return SILC_PACKET_NONE;
581 silc_buffer_pull(buffer, len);
582 ret = silc_buffer_unformat(buffer,
583 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
585 SILC_STR_UI_CHAR(&dst_id_type),
586 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
588 SILC_STR_UI_XNSTRING(NULL, padlen),
591 return SILC_PACKET_NONE;
593 if (src_id_type > SILC_ID_CHANNEL || dst_id_type > SILC_ID_CHANNEL) {
594 SILC_LOG_ERROR(("Bad ID types in packet (%d and %d)",
595 src_id_type, dst_id_type));
596 return SILC_PACKET_NONE;
599 ctx->src_id_len = src_id_len;
600 ctx->dst_id_len = dst_id_len;
601 ctx->src_id_type = src_id_type;
602 ctx->dst_id_type = dst_id_type;
603 ctx->padlen = padlen;
605 silc_buffer_push(buffer, len);
607 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
608 ctx->buffer->data, ctx->buffer->len);
610 /* Pull SILC header and padding from packet */
611 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
612 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
614 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
619 /* Perform special SILC Packet header parsing. This is required to some
620 packet types that have the data payload encrypted with different key
621 than the header area plus padding of the packet. Hence, this parses
622 the header in a way that it does not take the data area into account
623 and parses the header and padding area only. */
625 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx,
628 SilcBuffer buffer = ctx->buffer;
631 SilcUInt8 src_id_len, src_id_type, dst_id_len, dst_id_type, padlen;
633 SILC_LOG_DEBUG(("Parsing incoming packet"));
635 /* Check the length of the buffer */
636 if (buffer->len < SILC_PACKET_MIN_LEN) {
637 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
638 return SILC_PACKET_NONE;
641 /* Parse the buffer. This parses the SILC header of the packet. */
642 len = silc_buffer_unformat(buffer,
643 SILC_STR_UI_SHORT(&ctx->truelen),
644 SILC_STR_UI_CHAR(&ctx->flags),
645 SILC_STR_UI_CHAR(&ctx->type),
646 SILC_STR_UI_CHAR(&padlen),
647 SILC_STR_UI_CHAR(&tmp),
648 SILC_STR_UI_CHAR(&src_id_len),
649 SILC_STR_UI_CHAR(&dst_id_len),
650 SILC_STR_UI_CHAR(&src_id_type),
652 if (len == -1 || tmp != 0) {
653 SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
654 return SILC_PACKET_NONE;
657 if (src_id_len > SILC_PACKET_MAX_ID_LEN ||
658 dst_id_len > SILC_PACKET_MAX_ID_LEN) {
659 SILC_LOG_ERROR(("Bad ID lengths in packet (%d and %d)",
660 src_id_len, dst_id_len));
661 return SILC_PACKET_NONE;
664 silc_buffer_pull(buffer, len);
665 ret = silc_buffer_unformat(buffer,
666 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
668 SILC_STR_UI_CHAR(&dst_id_type),
669 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
671 SILC_STR_UI_XNSTRING(NULL, padlen),
674 SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
675 return SILC_PACKET_NONE;
678 if (src_id_type > SILC_ID_CHANNEL || dst_id_type > SILC_ID_CHANNEL) {
679 SILC_LOG_ERROR(("Bad ID types in packet (%d and %d)",
680 src_id_type, dst_id_type));
681 return SILC_PACKET_NONE;
684 ctx->src_id_len = src_id_len;
685 ctx->dst_id_len = dst_id_len;
686 ctx->src_id_type = src_id_type;
687 ctx->dst_id_type = dst_id_type;
688 ctx->padlen = padlen;
690 silc_buffer_push(buffer, len);
692 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
693 ctx->buffer->data, ctx->buffer->len);
695 /* Pull SILC header and padding from packet */
696 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
697 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
699 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
704 /* Allocate packet context */
706 SilcPacketContext *silc_packet_context_alloc(void)
708 SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
715 /* Increse the reference count of the packet context. */
717 SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
720 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users - 1,
725 /* Decrese the reference count of the packet context and free it only if
728 void silc_packet_context_free(SilcPacketContext *ctx)
731 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users + 1,
736 silc_buffer_free(ctx->buffer);
738 silc_free(ctx->src_id);
740 silc_free(ctx->dst_id);