5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 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];
116 /* Compute HMAC. This assumes that HMAC is created from the entire
117 data area thus this uses the length found in buffer, not the length
120 silc_hmac_make(hmac, buffer->data, buffer->len, mac);
121 silc_buffer_put_tail(buffer, mac, hmac->hash->hash->hash_len);
122 memset(mac, 0, sizeof(mac));
125 /* Encrypt the data area of the packet. 2 bytes of the packet
126 are not encrypted. */
128 SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d (%d)",
129 cipher->cipher->name, len, len - 2));
130 cipher->cipher->encrypt(cipher->context, buffer->data + 2,
131 buffer->data + 2, len - 2, cipher->iv);
134 /* Pull the HMAC into the visible data area in the buffer */
136 silc_buffer_pull_tail(buffer, hmac->hash->hash->hash_len);
139 /* Assembles a new packet to be ready for send out. The buffer sent as
140 argument must include the data to be sent and it must not be encrypted.
141 The packet also must have enough free space so that the SILC header
142 and padding maybe added to the packet. The packet is encrypted after
143 this function has returned.
145 The buffer sent as argument should be something like following:
147 --------------------------------------------
148 | head | data | tail |
149 --------------------------------------------
153 So that the SILC header and 1 - 16 bytes of padding can fit to
154 the buffer. After assembly the buffer might look like this:
156 --------------------------------------------
158 --------------------------------------------
160 Start of assembled packet
162 Packet construct is as follows (* = won't be encrypted):
165 2 bytes Payload length (*)
168 1 byte Source ID Type
169 2 bytes Source ID Length
171 1 byte Destination ID Type
172 2 bytes Destination ID Length
173 x bytes Destination ID
179 All fields in the packet will be authenticated by MAC. The MAC is
180 not computed here, it must be computed differently before encrypting
185 void silc_packet_assemble(SilcPacketContext *ctx)
187 unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
190 SILC_LOG_DEBUG(("Assembling outgoing packet"));
192 /* Get the true length of the packet. This is saved as payload length
193 into the packet header. This does not include the length of the
196 ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN +
197 ctx->src_id_len + ctx->dst_id_len;
199 /* Calculate the length of the padding. The padding is calculated from
200 the data that will be encrypted. As protocol states 3 first bytes
201 of the packet are not encrypted they are not included in the
202 padding calculation. */
204 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
206 /* Put the start of the data section to the right place. */
207 silc_buffer_push(ctx->buffer, SILC_PACKET_HEADER_LEN +
208 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
210 /* Get random padding */
212 for (i = 0; i < ctx->padlen; i++) tmppad[i] = silc_rng_get_byte(ctx->rng);
214 /* XXX: For testing - to be removed */
215 memset(tmppad, 65, sizeof(tmppad));
218 /* Create the packet. This creates the SILC header and adds padding,
219 rest of the buffer remains as it is. */
220 silc_buffer_format(ctx->buffer,
221 SILC_STR_UI_SHORT(ctx->truelen),
222 SILC_STR_UI_CHAR(ctx->flags),
223 SILC_STR_UI_CHAR(ctx->type),
224 SILC_STR_UI_SHORT(ctx->src_id_len),
225 SILC_STR_UI_SHORT(ctx->dst_id_len),
226 SILC_STR_UI_CHAR(ctx->src_id_type),
227 SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len),
228 SILC_STR_UI_CHAR(ctx->dst_id_type),
229 SILC_STR_UI_XNSTRING(ctx->dst_id, ctx->dst_id_len),
230 SILC_STR_UI_XNSTRING(tmppad, ctx->padlen),
233 SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len),
234 ctx->buffer->data, ctx->buffer->len);
236 SILC_LOG_DEBUG(("Outgoing packet assembled"));
239 /* Prepare outgoing data buffer for packet sending. This moves the data
240 area so that new packet may be added into it. If needed this allocates
241 more space to the buffer. This handles directly the connection's
242 outgoing buffer in SilcSocketConnection object. */
244 void silc_packet_send_prepare(SilcSocketConnection sock,
245 unsigned int header_len,
247 unsigned int data_len)
251 totlen = header_len + padlen + data_len;
253 /* Prepare the outgoing buffer for packet sending. */
255 /* Allocate new buffer. This is done only once per connection. */
256 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
258 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
259 silc_buffer_pull_tail(sock->outbuf, totlen);
260 silc_buffer_pull(sock->outbuf, header_len + padlen);
262 if (SILC_IS_OUTBUF_PENDING(sock)) {
263 /* There is some pending data in the buffer. */
265 /* Allocate more space if needed */
266 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
267 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
268 sock->outbuf = silc_buffer_realloc(sock->outbuf,
269 sock->outbuf->truelen + totlen);
272 oldlen = sock->outbuf->len;
273 silc_buffer_pull_tail(sock->outbuf, totlen);
274 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
276 /* Buffer is free for use */
277 silc_buffer_clear(sock->outbuf);
278 silc_buffer_pull_tail(sock->outbuf, totlen);
279 silc_buffer_pull(sock->outbuf, header_len + padlen);
284 /******************************************************************************
286 Packet Reception Routines
288 ******************************************************************************/
290 /* Reads data from the socket connection into the incoming data buffer.
291 However, this does not parse the packet, it only reads some amount from
292 the network. If there are more data available that can be read at a time
293 the rest of the data will be read later with a timeout and only after
294 that the packet is ready to be parsed.
296 The destination buffer sent as argument must be initialized before
297 calling this function, and, the data section and the start of the tail
298 section must be same. Ie. we add the read data to the tail section of
299 the buffer hence the data section is the start of the buffer.
301 This returns amount of bytes read or -1 on error or -2 on case where
302 all of the data could not be read at once. */
304 int silc_packet_read(int sock, SilcBuffer dest)
307 unsigned char buf[SILC_PACKET_READ_SIZE];
309 SILC_LOG_DEBUG(("Reading data from socket %d", sock));
311 /* Read the data from the socket. */
312 len = read(sock, buf, sizeof(buf));
314 if (errno == EAGAIN || errno == EINTR) {
315 SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
318 SILC_LOG_ERROR(("Cannot read from socket: %d", strerror(errno)));
325 /* Insert the data to the buffer. If the data doesn't fit to the
326 buffer space is allocated for the buffer. */
327 /* XXX: This may actually be bad thing as if there is pending data in
328 the buffer they will be lost! */
331 /* If the data doesn't fit we just have to allocate a whole new
333 if (dest->truelen <= len) {
335 /* Free the old buffer */
336 memset(dest->head, 'F', dest->truelen);
337 silc_free(dest->head);
339 /* Allocate new data area */
340 len += SILC_PACKET_DEFAULT_SIZE;
341 dest->data = silc_calloc(len, sizeof(char));
344 dest->head = dest->data;
345 dest->data = dest->data;
346 dest->tail = dest->data;
347 dest->end = dest->data + dest->truelen;
348 len -= SILC_PACKET_DEFAULT_SIZE;
351 silc_buffer_put_tail(dest, buf, len);
352 silc_buffer_pull_tail(dest, len);
355 SILC_LOG_DEBUG(("Read %d bytes", len));
360 /* Processes the received data. This checks the received data and
361 calls parser callback that handles the actual packet decryption
362 and parsing. If more than one packet was received this calls the
363 parser multiple times. The parser callback will get context
364 SilcPacketParserContext that includes the packet and the `context'
365 sent to this function. */
367 void silc_packet_receive_process(SilcSocketConnection sock,
368 SilcCipher cipher, SilcHmac hmac,
369 SilcPacketParserCallback parser,
372 SilcPacketParserContext *parse_ctx;
373 int packetlen, paddedlen, count, mac_len = 0;
375 /* We need at least 2 bytes of data to be able to start processing
377 if (sock->inbuf->len < 2)
381 mac_len = hmac->hash->hash->hash_len;
383 /* Parse the packets from the data */
385 while (sock->inbuf->len > 0) {
386 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
390 if (packetlen < SILC_PACKET_MIN_LEN) {
391 SILC_LOG_DEBUG(("Received invalid packet, dropped"));
395 if (sock->inbuf->len < paddedlen + mac_len) {
396 SILC_LOG_DEBUG(("Received partial packet, waiting for the rest"));
400 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
401 parse_ctx->packet = silc_packet_context_alloc();
402 parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
403 parse_ctx->sock = sock;
404 parse_ctx->cipher = cipher;
405 parse_ctx->hmac = hmac;
406 parse_ctx->context = context;
408 silc_buffer_pull_tail(parse_ctx->packet->buffer,
409 SILC_BUFFER_END(parse_ctx->packet->buffer));
410 silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data,
411 paddedlen + mac_len);
413 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
414 parse_ctx->packet->buffer->len),
415 parse_ctx->packet->buffer->data,
416 parse_ctx->packet->buffer->len);
418 /* Call the parser */
420 (*parser)(parse_ctx);
422 /* Pull the packet from inbuf thus we'll get the next one
424 silc_buffer_pull(sock->inbuf, paddedlen);
426 silc_buffer_pull(sock->inbuf, mac_len);
429 silc_buffer_clear(sock->inbuf);
432 /* Receives packet from network and reads the data into connection's
433 incoming data buffer. If the data was read directly this returns the
434 read bytes, if error occured this returns -1, if the data could not
435 be read directly at this time this returns -2 in which case the data
436 should be read again at some later time, or If EOF occured this returns
439 int silc_packet_receive(SilcSocketConnection sock)
443 SILC_LOG_DEBUG(("Receiving packet from %s:%d [%s]", sock->hostname,
445 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
446 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
447 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
450 /* Allocate the incoming data buffer if not done already. */
452 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
454 /* Read some data from connection */
455 ret = silc_packet_read(sock->sock, sock->inbuf);
460 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
461 after packet has been totally decrypted and parsed. */
463 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
467 unsigned char mac[32];
469 SILC_LOG_DEBUG(("Verifying MAC"));
471 /* Compute HMAC of packet */
472 memset(mac, 0, sizeof(mac));
473 silc_hmac_make(hmac, buffer->data, buffer->len, mac);
475 /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
476 if (memcmp(mac, buffer->tail, hmac->hash->hash->hash_len)) {
477 SILC_LOG_DEBUG(("MAC failed"));
481 SILC_LOG_DEBUG(("MAC is Ok"));
482 memset(mac, 0, sizeof(mac));
488 /* Decrypts rest of the packet (after decrypting just the SILC header).
489 After calling this function the packet is ready to be parsed by calling
490 silc_packet_parse. If everything goes without errors this returns TRUE,
491 if packet is malformed this returns FALSE. */
493 static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
498 /* Pull MAC from packet before decryption */
500 if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
501 silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
503 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
508 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
510 /* Decrypt rest of the packet */
511 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
512 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
513 buffer->data + 2, buffer->len - 2,
515 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
517 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
518 buffer->data, buffer->len);
524 /* Decrypts rest of the SILC Packet header that has been decrypted partly
525 already. This decrypts the padding of the packet also. After calling
526 this function the packet is ready to be parsed by calling function
527 silc_packet_parse. This is used in special packet reception (protocol
528 defines the way of decrypting special packets). */
530 static int silc_packet_decrypt_rest_special(SilcCipher cipher,
534 /* Decrypt rest of the header plus padding */
536 unsigned short truelen, len1, len2, padlen;
538 /* Pull MAC from packet before decryption */
540 if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
541 silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
543 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
548 SILC_LOG_DEBUG(("Decrypting rest of the header"));
550 SILC_GET16_MSB(len1, &buffer->data[4]);
551 SILC_GET16_MSB(len2, &buffer->data[6]);
553 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
554 padlen = SILC_PACKET_PADLEN(truelen);
555 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
557 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
558 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
559 buffer->data + 2, len1 - 2,
561 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
567 /* Decrypts a packet. This assumes that typical SILC packet is the
568 packet to be decrypted and thus checks for normal and special SILC
569 packets and can handle both of them. This also computes and checks
570 the HMAC of the packet. If any other special or customized decryption
571 processing is required this function cannot be used. This returns
572 -1 on error, 0 when packet is normal packet and 1 when the packet
573 is special and requires special processing. */
575 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
576 SilcBuffer buffer, SilcPacketContext *packet)
579 /* Decrypt start of the packet header */
581 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
582 buffer->data + 2, SILC_PACKET_MIN_HEADER_LEN - 2,
585 /* If the packet type is not any special type lets decrypt rest
586 of the packet here. */
587 if ((buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
588 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY)) ||
589 buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE) {
591 /* Normal packet, decrypt rest of the packet */
592 if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
596 if (!silc_packet_check_mac(hmac, buffer))
601 /* Packet requires special handling, decrypt rest of the header.
602 This only decrypts. */
603 if (!silc_packet_decrypt_rest_special(cipher, hmac, buffer))
607 if (!silc_packet_check_mac(hmac, buffer))
614 /* Parses the packet. This is called when a whole packet is ready to be
615 parsed. The buffer sent must be already decrypted before calling this
616 function. The len argument must be the true length of the packet. This
617 function returns the type of the packet. The data section of the
618 buffer is parsed, not head or tail sections. */
620 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
622 SilcBuffer buffer = ctx->buffer;
625 SILC_LOG_DEBUG(("Parsing incoming packet"));
627 /* Check the length of the buffer */
628 if (buffer->len < SILC_PACKET_MIN_LEN) {
629 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
630 return SILC_PACKET_NONE;
633 /* Parse the buffer. This parses the SILC header of the packet. */
634 len = silc_buffer_unformat(buffer,
635 SILC_STR_UI_SHORT(&ctx->truelen),
636 SILC_STR_UI_CHAR(&ctx->flags),
637 SILC_STR_UI_CHAR(&ctx->type),
638 SILC_STR_UI_SHORT(&ctx->src_id_len),
639 SILC_STR_UI_SHORT(&ctx->dst_id_len),
640 SILC_STR_UI_CHAR(&ctx->src_id_type),
643 return SILC_PACKET_NONE;
645 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
646 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
647 SILC_LOG_ERROR(("Bad ID lengths in packet"));
648 return SILC_PACKET_NONE;
651 /* Calculate length of padding in packet */
652 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
654 silc_buffer_pull(buffer, len);
655 ret = silc_buffer_unformat(buffer,
656 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
658 SILC_STR_UI_CHAR(&ctx->dst_id_type),
659 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
661 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
664 return SILC_PACKET_NONE;
666 silc_buffer_push(buffer, len);
668 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
669 ctx->buffer->data, ctx->buffer->len);
671 /* Pull SILC header and padding from packet */
672 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
673 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
675 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
680 /* Perform special SILC Packet header parsing. This is required to some
681 packet types that have the data payload encrypted with different key
682 than the header area plus padding of the packet. Hence, this parses
683 the header in a way that it does not take the data area into account
684 and parses the header and padding area only. */
686 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
688 SilcBuffer buffer = ctx->buffer;
689 int len, tmplen, ret;
691 SILC_LOG_DEBUG(("Parsing incoming packet"));
693 /* Check the length of the buffer */
694 if (buffer->len < SILC_PACKET_MIN_LEN) {
695 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
696 return SILC_PACKET_NONE;
699 /* Parse the buffer. This parses the SILC header of the packet. */
700 len = silc_buffer_unformat(buffer,
701 SILC_STR_UI_SHORT(&ctx->truelen),
702 SILC_STR_UI_CHAR(&ctx->flags),
703 SILC_STR_UI_CHAR(&ctx->type),
704 SILC_STR_UI_SHORT(&ctx->src_id_len),
705 SILC_STR_UI_SHORT(&ctx->dst_id_len),
706 SILC_STR_UI_CHAR(&ctx->src_id_type),
709 return SILC_PACKET_NONE;
711 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
712 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
713 SILC_LOG_ERROR(("Bad ID lengths in packet"));
714 return SILC_PACKET_NONE;
717 /* Calculate length of padding in packet. As this is special packet
718 the data area is not used in the padding calculation as it won't
719 be decrypted by the caller. */
720 tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len;
721 ctx->padlen = SILC_PACKET_PADLEN(tmplen);
723 silc_buffer_pull(buffer, len);
724 ret = silc_buffer_unformat(buffer,
725 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
727 SILC_STR_UI_CHAR(&ctx->dst_id_type),
728 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
730 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
733 return SILC_PACKET_NONE;
735 silc_buffer_push(buffer, len);
737 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
738 ctx->buffer->data, ctx->buffer->len);
740 /* Pull SILC header and padding from packet */
741 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
742 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
744 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
749 /* Allocate packet context */
751 SilcPacketContext *silc_packet_context_alloc()
753 SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
758 /* Increse the reference count of the packet context. */
760 SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
763 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users - 1,
768 /* Decrese the reference count of the packet context and free it only if
771 void silc_packet_context_free(SilcPacketContext *ctx)
774 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users + 1,
779 silc_buffer_free(ctx->buffer);
781 silc_free(ctx->src_id);
783 silc_free(ctx->dst_id);