5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
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; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Created: Fri Jul 25 18:52:14 1997
25 #include "silcincludes.h"
27 /******************************************************************************
29 Packet Sending Routines
31 ******************************************************************************/
33 /* Writes data from encrypted buffer to the socket connection. If the
34 data cannot be written at once, it will be written later with a timeout.
35 The data is written from the data section of the buffer, not from head
36 or tail section. This automatically pulls the data section towards end
37 after writing the data. */
39 int silc_packet_write(int sock, SilcBuffer src)
43 SILC_LOG_DEBUG(("Writing data to socket %d", sock));
46 ret = write(sock, src->data, src->len);
48 if (errno == EAGAIN) {
49 SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
52 SILC_LOG_ERROR(("Cannot write to socket: %s", strerror(errno)));
56 silc_buffer_pull(src, ret);
59 SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
64 /* Actually sends the packet. This flushes the connections outgoing data
65 buffer. If data is sent directly to the network this returns the bytes
66 written, if error occured this returns -1 and if the data could not
67 be written directly to the network at this time this returns -2, in
68 which case the data should be queued by the caller and sent at some
69 later time. If `force_send' is TRUE this attempts to write the data
70 directly to the network, if FALSE, this returns -2. */
72 int silc_packet_send(SilcSocketConnection sock, int force_send)
74 SILC_LOG_DEBUG(("Sending packet to %s:%d [%s]", sock->hostname,
76 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
77 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
78 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
81 /* Send now if forced to do so */
82 if (force_send == TRUE) {
85 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
87 /* Write to network */
88 ret = silc_packet_write(sock->sock, sock->outbuf);
91 SILC_LOG_ERROR(("Error sending packet, dropped"));
96 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
99 SILC_LOG_DEBUG(("Packet in queue"));
104 /* Encrypts a packet. This also creates HMAC of the packet before
105 encryption and adds the HMAC at the end of the buffer. This assumes
106 that there is enough free space at the end of the buffer to add the
107 computed HMAC. This is the normal way of encrypting packets, if some
108 other process of HMAC computing and encryption is needed this function
111 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac,
112 SilcBuffer buffer, unsigned int len)
114 unsigned char mac[32];
115 unsigned int mac_len;
117 /* Compute HMAC. This assumes that HMAC is created from the entire
118 data area thus this uses the length found in buffer, not the length
121 silc_hmac_make(hmac, buffer->data, buffer->len, mac, &mac_len);
122 silc_buffer_put_tail(buffer, mac, mac_len);
123 memset(mac, 0, sizeof(mac));
126 /* Encrypt the data area of the packet. 2 bytes of the packet
127 are not encrypted. */
129 SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d (%d)",
130 cipher->cipher->name, len, len - 2));
131 cipher->cipher->encrypt(cipher->context, buffer->data + 2,
132 buffer->data + 2, len - 2, cipher->iv);
135 /* Pull the HMAC into the visible data area in the buffer */
137 silc_buffer_pull_tail(buffer, mac_len);
140 /* Assembles a new packet to be ready for send out. The buffer sent as
141 argument must include the data to be sent and it must not be encrypted.
142 The packet also must have enough free space so that the SILC header
143 and padding maybe added to the packet. The packet is encrypted after
144 this function has returned.
146 The buffer sent as argument should be something like following:
148 --------------------------------------------
149 | head | data | tail |
150 --------------------------------------------
154 So that the SILC header and 1 - 16 bytes of padding can fit to
155 the buffer. After assembly the buffer might look like this:
157 --------------------------------------------
159 --------------------------------------------
161 Start of assembled packet
163 Packet construct is as follows (* = won't be encrypted):
166 2 bytes Payload length (*)
169 1 byte Source ID Type
170 2 bytes Source ID Length
172 1 byte Destination ID Type
173 2 bytes Destination ID Length
174 x bytes Destination ID
180 All fields in the packet will be authenticated by MAC. The MAC is
181 not computed here, it must be computed differently before encrypting
186 void silc_packet_assemble(SilcPacketContext *ctx)
188 unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
191 SILC_LOG_DEBUG(("Assembling outgoing packet"));
193 /* Get the true length of the packet. This is saved as payload length
194 into the packet header. This does not include the length of the
197 ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN +
198 ctx->src_id_len + ctx->dst_id_len;
200 /* Calculate the length of the padding. The padding is calculated from
201 the data that will be encrypted. As protocol states 3 first bytes
202 of the packet are not encrypted they are not included in the
203 padding calculation. */
205 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
207 /* Put the start of the data section to the right place. */
208 silc_buffer_push(ctx->buffer, SILC_PACKET_HEADER_LEN +
209 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
211 /* Get random padding */
213 for (i = 0; i < ctx->padlen; i++) tmppad[i] = silc_rng_global_get_byte();
215 /* XXX: For testing - to be removed */
216 memset(tmppad, 65, sizeof(tmppad));
219 /* Create the packet. This creates the SILC header and adds padding,
220 rest of the buffer remains as it is. */
221 silc_buffer_format(ctx->buffer,
222 SILC_STR_UI_SHORT(ctx->truelen),
223 SILC_STR_UI_CHAR(ctx->flags),
224 SILC_STR_UI_CHAR(ctx->type),
225 SILC_STR_UI_SHORT(ctx->src_id_len),
226 SILC_STR_UI_SHORT(ctx->dst_id_len),
227 SILC_STR_UI_CHAR(ctx->src_id_type),
228 SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len),
229 SILC_STR_UI_CHAR(ctx->dst_id_type),
230 SILC_STR_UI_XNSTRING(ctx->dst_id, ctx->dst_id_len),
231 SILC_STR_UI_XNSTRING(tmppad, ctx->padlen),
234 SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len),
235 ctx->buffer->data, ctx->buffer->len);
237 SILC_LOG_DEBUG(("Outgoing packet assembled"));
240 /* Prepare outgoing data buffer for packet sending. This moves the data
241 area so that new packet may be added into it. If needed this allocates
242 more space to the buffer. This handles directly the connection's
243 outgoing buffer in SilcSocketConnection object. */
245 void silc_packet_send_prepare(SilcSocketConnection sock,
246 unsigned int header_len,
248 unsigned int data_len)
252 totlen = header_len + padlen + data_len;
254 /* Prepare the outgoing buffer for packet sending. */
256 /* Allocate new buffer. This is done only once per connection. */
257 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
259 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
260 silc_buffer_pull_tail(sock->outbuf, totlen);
261 silc_buffer_pull(sock->outbuf, header_len + padlen);
263 if (SILC_IS_OUTBUF_PENDING(sock)) {
264 /* There is some pending data in the buffer. */
266 /* Allocate more space if needed */
267 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
268 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
269 sock->outbuf = silc_buffer_realloc(sock->outbuf,
270 sock->outbuf->truelen + totlen);
273 oldlen = sock->outbuf->len;
274 silc_buffer_pull_tail(sock->outbuf, totlen);
275 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
277 /* Buffer is free for use */
278 silc_buffer_clear(sock->outbuf);
279 silc_buffer_pull_tail(sock->outbuf, totlen);
280 silc_buffer_pull(sock->outbuf, header_len + padlen);
285 /******************************************************************************
287 Packet Reception Routines
289 ******************************************************************************/
291 /* Reads data from the socket connection into the incoming data buffer.
292 However, this does not parse the packet, it only reads some amount from
293 the network. If there are more data available that can be read at a time
294 the rest of the data will be read later with a timeout and only after
295 that the packet is ready to be parsed.
297 The destination buffer sent as argument must be initialized before
298 calling this function, and, the data section and the start of the tail
299 section must be same. Ie. we add the read data to the tail section of
300 the buffer hence the data section is the start of the buffer.
302 This returns amount of bytes read or -1 on error or -2 on case where
303 all of the data could not be read at once. */
305 int silc_packet_read(int sock, SilcBuffer dest)
308 unsigned char buf[SILC_PACKET_READ_SIZE];
310 SILC_LOG_DEBUG(("Reading data from socket %d", sock));
312 /* Read the data from the socket. */
313 len = read(sock, buf, sizeof(buf));
315 if (errno == EAGAIN || errno == EINTR) {
316 SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
319 SILC_LOG_ERROR(("Cannot read from socket: %d:%s", sock, strerror(errno)));
326 /* Insert the data to the buffer. If the data doesn't fit to the
327 buffer space is allocated for the buffer. */
328 /* XXX: This may actually be bad thing as if there is pending data in
329 the buffer they will be lost! */
332 /* If the data doesn't fit we just have to allocate a whole new
334 if (dest->truelen <= len) {
336 /* Free the old buffer */
337 memset(dest->head, 'F', dest->truelen);
338 silc_free(dest->head);
340 /* Allocate new data area */
341 len += SILC_PACKET_DEFAULT_SIZE;
342 dest->data = silc_calloc(len, sizeof(char));
345 dest->head = dest->data;
346 dest->data = dest->data;
347 dest->tail = dest->data;
348 dest->end = dest->data + dest->truelen;
349 len -= SILC_PACKET_DEFAULT_SIZE;
352 silc_buffer_put_tail(dest, buf, len);
353 silc_buffer_pull_tail(dest, len);
356 SILC_LOG_DEBUG(("Read %d bytes", len));
361 /* Processes the received data. This checks the received data and
362 calls parser callback that handles the actual packet decryption
363 and parsing. If more than one packet was received this calls the
364 parser multiple times. The parser callback will get context
365 SilcPacketParserContext that includes the packet and the `context'
366 sent to this function. */
368 void silc_packet_receive_process(SilcSocketConnection sock,
369 SilcCipher cipher, SilcHmac hmac,
370 SilcPacketParserCallback parser,
373 SilcPacketParserContext *parse_ctx;
374 int packetlen, paddedlen, count, mac_len = 0;
376 /* We need at least 2 bytes of data to be able to start processing
378 if (sock->inbuf->len < 2)
382 mac_len = hmac->hmac->len;
384 /* Parse the packets from the data */
386 while (sock->inbuf->len > 0) {
387 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
391 if (packetlen < SILC_PACKET_MIN_LEN) {
392 SILC_LOG_DEBUG(("Received invalid packet, dropped"));
396 if (sock->inbuf->len < paddedlen + mac_len) {
397 SILC_LOG_DEBUG(("Received partial packet, waiting for the rest"));
401 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
402 parse_ctx->packet = silc_packet_context_alloc();
403 parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
404 parse_ctx->sock = sock;
405 parse_ctx->cipher = cipher;
406 parse_ctx->hmac = hmac;
407 parse_ctx->context = context;
409 silc_buffer_pull_tail(parse_ctx->packet->buffer,
410 SILC_BUFFER_END(parse_ctx->packet->buffer));
411 silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data,
412 paddedlen + mac_len);
414 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
415 parse_ctx->packet->buffer->len),
416 parse_ctx->packet->buffer->data,
417 parse_ctx->packet->buffer->len);
419 /* Call the parser */
421 (*parser)(parse_ctx);
423 /* Pull the packet from inbuf thus we'll get the next one
425 silc_buffer_pull(sock->inbuf, paddedlen);
427 silc_buffer_pull(sock->inbuf, mac_len);
430 silc_buffer_clear(sock->inbuf);
433 /* Receives packet from network and reads the data into connection's
434 incoming data buffer. If the data was read directly this returns the
435 read bytes, if error occured this returns -1, if the data could not
436 be read directly at this time this returns -2 in which case the data
437 should be read again at some later time, or If EOF occured this returns
440 int silc_packet_receive(SilcSocketConnection sock)
444 SILC_LOG_DEBUG(("Receiving packet from %s:%d [%s]", sock->hostname,
446 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
447 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
448 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
451 /* Allocate the incoming data buffer if not done already. */
453 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
455 /* Read some data from connection */
456 ret = silc_packet_read(sock->sock, sock->inbuf);
461 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
462 after packet has been totally decrypted and parsed. */
464 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
468 unsigned char mac[32];
469 unsigned int mac_len;
471 SILC_LOG_DEBUG(("Verifying MAC"));
473 /* Compute HMAC of packet */
474 memset(mac, 0, sizeof(mac));
475 silc_hmac_make(hmac, buffer->data, buffer->len, mac, &mac_len);
477 /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
478 if (memcmp(mac, buffer->tail, mac_len)) {
479 SILC_LOG_DEBUG(("MAC failed"));
483 SILC_LOG_DEBUG(("MAC is Ok"));
484 memset(mac, 0, sizeof(mac));
490 /* Decrypts rest of the packet (after decrypting just the SILC header).
491 After calling this function the packet is ready to be parsed by calling
492 silc_packet_parse. If everything goes without errors this returns TRUE,
493 if packet is malformed this returns FALSE. */
495 static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
500 /* Pull MAC from packet before decryption */
502 if ((buffer->len - hmac->hmac->len) > SILC_PACKET_MIN_LEN) {
503 silc_buffer_push_tail(buffer, hmac->hmac->len);
505 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
510 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
512 /* Decrypt rest of the packet */
513 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
514 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
515 buffer->data + 2, buffer->len - 2,
517 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
519 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
520 buffer->data, buffer->len);
526 /* Decrypts rest of the SILC Packet header that has been decrypted partly
527 already. This decrypts the padding of the packet also. After calling
528 this function the packet is ready to be parsed by calling function
529 silc_packet_parse. This is used in special packet reception (protocol
530 defines the way of decrypting special packets). */
532 static int silc_packet_decrypt_rest_special(SilcCipher cipher,
536 /* Decrypt rest of the header plus padding */
538 unsigned short truelen, len1, len2, padlen;
540 /* Pull MAC from packet before decryption */
542 if ((buffer->len - hmac->hmac->len) > SILC_PACKET_MIN_LEN) {
543 silc_buffer_push_tail(buffer, hmac->hmac->len);
545 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
550 SILC_LOG_DEBUG(("Decrypting rest of the header"));
552 SILC_GET16_MSB(len1, &buffer->data[4]);
553 SILC_GET16_MSB(len2, &buffer->data[6]);
555 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
556 padlen = SILC_PACKET_PADLEN(truelen);
557 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
559 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
560 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
561 buffer->data + 2, len1 - 2,
563 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
569 /* Decrypts a packet. This assumes that typical SILC packet is the
570 packet to be decrypted and thus checks for normal and special SILC
571 packets and can handle both of them. This also computes and checks
572 the HMAC of the packet. If any other special or customized decryption
573 processing is required this function cannot be used. This returns
574 -1 on error, 0 when packet is normal packet and 1 when the packet
575 is special and requires special processing.
577 The `check_packet' is a callback funtion that this function will
578 call. The callback relates to the checking whether the packet is
579 normal packet or special packet and how it should be processed. If
580 the callback return TRUE the packet is normal and FALSE if the packet
581 is special and requires special procesing. */
583 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
584 SilcBuffer buffer, SilcPacketContext *packet,
585 SilcPacketCheckDecrypt check_packet,
590 /* Decrypt start of the packet header */
592 silc_cipher_decrypt(cipher, buffer->data + 2, buffer->data + 2,
593 SILC_PACKET_MIN_HEADER_LEN - 2, cipher->iv);
595 /* Do packet checking, whether the packet is normal or special */
596 check = check_packet((SilcPacketType)buffer->data[3], buffer,
599 /* If the packet type is not any special type lets decrypt rest
600 of the packet here. */
602 /* Normal packet, decrypt rest of the packet */
603 if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
607 if (!silc_packet_check_mac(hmac, buffer))
612 /* Packet requires special handling, decrypt rest of the header.
613 This only decrypts. */
614 if (!silc_packet_decrypt_rest_special(cipher, hmac, buffer))
618 if (!silc_packet_check_mac(hmac, buffer))
625 /* Parses the packet. This is called when a whole packet is ready to be
626 parsed. The buffer sent must be already decrypted before calling this
627 function. The len argument must be the true length of the packet. This
628 function returns the type of the packet. The data section of the
629 buffer is parsed, not head or tail sections. */
631 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
633 SilcBuffer buffer = ctx->buffer;
636 SILC_LOG_DEBUG(("Parsing incoming packet"));
638 /* Check the length of the buffer */
639 if (buffer->len < SILC_PACKET_MIN_LEN) {
640 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
641 return SILC_PACKET_NONE;
644 /* Parse the buffer. This parses the SILC header of the packet. */
645 len = silc_buffer_unformat(buffer,
646 SILC_STR_UI_SHORT(&ctx->truelen),
647 SILC_STR_UI_CHAR(&ctx->flags),
648 SILC_STR_UI_CHAR(&ctx->type),
649 SILC_STR_UI_SHORT(&ctx->src_id_len),
650 SILC_STR_UI_SHORT(&ctx->dst_id_len),
651 SILC_STR_UI_CHAR(&ctx->src_id_type),
654 return SILC_PACKET_NONE;
656 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
657 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
658 SILC_LOG_ERROR(("Bad ID lengths in packet"));
659 return SILC_PACKET_NONE;
662 /* Calculate length of padding in packet */
663 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
665 silc_buffer_pull(buffer, len);
666 ret = silc_buffer_unformat(buffer,
667 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
669 SILC_STR_UI_CHAR(&ctx->dst_id_type),
670 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
672 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
675 return SILC_PACKET_NONE;
677 silc_buffer_push(buffer, len);
679 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
680 ctx->buffer->data, ctx->buffer->len);
682 /* Pull SILC header and padding from packet */
683 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
684 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
686 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
691 /* Perform special SILC Packet header parsing. This is required to some
692 packet types that have the data payload encrypted with different key
693 than the header area plus padding of the packet. Hence, this parses
694 the header in a way that it does not take the data area into account
695 and parses the header and padding area only. */
697 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
699 SilcBuffer buffer = ctx->buffer;
700 int len, tmplen, ret;
702 SILC_LOG_DEBUG(("Parsing incoming packet"));
704 /* Check the length of the buffer */
705 if (buffer->len < SILC_PACKET_MIN_LEN) {
706 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
707 return SILC_PACKET_NONE;
710 /* Parse the buffer. This parses the SILC header of the packet. */
711 len = silc_buffer_unformat(buffer,
712 SILC_STR_UI_SHORT(&ctx->truelen),
713 SILC_STR_UI_CHAR(&ctx->flags),
714 SILC_STR_UI_CHAR(&ctx->type),
715 SILC_STR_UI_SHORT(&ctx->src_id_len),
716 SILC_STR_UI_SHORT(&ctx->dst_id_len),
717 SILC_STR_UI_CHAR(&ctx->src_id_type),
720 return SILC_PACKET_NONE;
722 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
723 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
724 SILC_LOG_ERROR(("Bad ID lengths in packet"));
725 return SILC_PACKET_NONE;
728 /* Calculate length of padding in packet. As this is special packet
729 the data area is not used in the padding calculation as it won't
730 be decrypted by the caller. */
731 tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len;
732 ctx->padlen = SILC_PACKET_PADLEN(tmplen);
734 silc_buffer_pull(buffer, len);
735 ret = silc_buffer_unformat(buffer,
736 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
738 SILC_STR_UI_CHAR(&ctx->dst_id_type),
739 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
741 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
744 return SILC_PACKET_NONE;
746 silc_buffer_push(buffer, len);
748 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
749 ctx->buffer->data, ctx->buffer->len);
751 /* Pull SILC header and padding from packet */
752 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
753 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
755 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
760 /* Allocate packet context */
762 SilcPacketContext *silc_packet_context_alloc()
764 SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
769 /* Increse the reference count of the packet context. */
771 SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
774 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users - 1,
779 /* Decrese the reference count of the packet context and free it only if
782 void silc_packet_context_free(SilcPacketContext *ctx)
785 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users + 1,
790 silc_buffer_free(ctx->buffer);
792 silc_free(ctx->src_id);
794 silc_free(ctx->dst_id);