X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcpacket.h;h=b2c9dd2790dc0b121ffc10c5f3919e452aa3dd01;hp=54e5453c0a6805670c397896e4687a45f40c09e2;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=83c73dffa89141bc59e62436abb63b3d3efca6bb diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index 54e5453c..b2c9dd27 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -17,7 +17,7 @@ */ -/****h* silccore/SilcPacketAPI +/****h* silccore/Packet Protocol Interface * * DESCRIPTION * @@ -51,14 +51,17 @@ /* Minimum packet length */ #define SILC_PACKET_MIN_LEN (SILC_PACKET_HEADER_LEN + 1) +/* Maximum packet length */ +#define SILC_PACKET_MAX_LEN 0xffff + /* Maximum length of ID */ -#define SILC_PACKET_MAX_ID_LEN 16 +#define SILC_PACKET_MAX_ID_LEN 28 /****d* silccore/SilcPacketAPI/SilcPacketType * * NAME * - * typedef unsigned char SilcPacketType; + * typedef SilcUInt8 SilcPacketType; * * DESCRIPTION * @@ -66,7 +69,7 @@ * * SOURCE */ -typedef unsigned char SilcPacketType; +typedef SilcUInt8 SilcPacketType; /* SILC Packet types. */ #define SILC_PACKET_NONE 0 /* NULL, never sent */ @@ -97,6 +100,7 @@ typedef unsigned char SilcPacketType; #define SILC_PACKET_KEY_AGREEMENT 25 /* Key Agreement request */ #define SILC_PACKET_RESUME_ROUTER 26 /* Backup router resume */ #define SILC_PACKET_FTP 27 /* File Transfer */ +#define SILC_PACKET_RESUME_CLIENT 28 /* Client resume */ #define SILC_PACKET_PRIVATE 200 /* Private range start */ #define SILC_PACKET_MAX 255 /* RESERVED */ @@ -106,20 +110,20 @@ typedef unsigned char SilcPacketType; * * NAME * - * typedef unsigned char SilcPacketVersion; + * typedef SilcUInt8 SilcPacketVersion; * * DESCRIPTION * * SILC packet version type definition. * ***/ -typedef unsigned char SilcPacketVersion; +typedef SilcUInt8 SilcPacketVersion; /****d* silccore/SilcPacketAPI/SilcPacketFlags * * NAME * - * typedef unsigned char SilcPacketFlags; + * typedef SilcUInt8 SilcPacketFlags; * * DESCRIPTION * @@ -127,17 +131,17 @@ typedef unsigned char SilcPacketVersion; * * SOURCE */ -typedef unsigned char SilcPacketFlags; +typedef SilcUInt8 SilcPacketFlags; /* All defined packet flags */ #define SILC_PACKET_FLAG_NONE 0x00 /* No flags */ #define SILC_PACKET_FLAG_PRIVMSG_KEY 0x01 /* Private message key */ #define SILC_PACKET_FLAG_LIST 0x02 /* Packet is a list */ #define SILC_PACKET_FLAG_BROADCAST 0x04 /* Packet is a broadcast */ +#define SILC_PACKET_FLAG_COMPRESSED 0x08 /* Payload is compressed */ /***/ /* Rest of flags still available -#define SILC_PACKET_FLAG_XXX 0x08 #define SILC_PACKET_FLAG_XXX 0x10 #define SILC_PACKET_FLAG_XXX 0x20 #define SILC_PACKET_FLAG_XXX 0x40 @@ -161,73 +165,81 @@ typedef unsigned char SilcPacketFlags; * * Short description of the fields following: * - * SilcBuffer buffer - * - * The data buffer. + * SilcUInt16 truelen * - * SilcPacketType type - * - * Type of the packet. Types are defined below. + * True length of the packet. This may be set by the caller before + * calling any of the silc_packet_* routines. If not provided the + * library will calculate the values. * * SilcPacketFlags flags * * Packet flags. Flags are defined above. * + * SilcPacketType type + * + * Type of the packet. Types are defined below. + * * unsigned char *src_id - * uint16 src_id_len - * unsigned char src_id_type + * SilcUInt8 src_id_len + * SilcUInt8 src_id_type * * Source ID, its length and type. On packet reception retuned ID's * are always the hash values of the ID's from the packet. * * unsigned char *dst_id; - * uint16 dst_id_len; - * unsigned char src_id_type; + * SilcUInt8 dst_id_len; + * SilcUInt8 src_id_type; * * Destination ID, its length and type. On packet reception retuned * ID's are always the hash values of the ID's from the packet. * - * uint16 truelen - * uint16 padlen - * - * The true lenght of the packet and the padded length of the packet. - * These may be set by the caller before calling any of the - * silc_packet_* routines. If not provided the library will calculate - * the values. + * bool long_pad + * + * If set to TRUE the packet will include the maximum padding allowed + * in SILC packet, which is 128 bytes. If FALSE only the amount of + * padding needed will be applied. * - * int users; + * SilcUInt16 users; * * Reference counter for this context. The context is freed only * after the reference counter hits zero. The counter is added * calling silc_packet_context_dup and decreased by calling the * silc_packet_context_free. * - * uint32 sequence; + * SilcUInt8 padlen * - * Packet sequence number. + * The padded length of the packet. This may be set by the caller + * before calling any of the silc_packet_* routines. If not provided + * the library will calculate the values. + * + * SilcUInt32 sequence; + * + * Packet sequence number. Set only when this context is a parsed + * packet. + * + * SilcBuffer buffer + * + * The actual packet data. Set only when this context is a parsed + * packet. * ***/ typedef struct { - SilcBuffer buffer; - - uint16 truelen; + SilcUInt16 truelen; SilcPacketFlags flags; SilcPacketType type; - uint8 padlen; unsigned char *src_id; - uint8 src_id_len; - uint8 src_id_type; - unsigned char *dst_id; - uint8 dst_id_len; - uint8 dst_id_type; - - int users; - bool long_pad; /* Set to TRUE to use maximum padding - in packet (up to 256 bytes). */ - - uint32 sequence; + unsigned int src_id_len : 5; + unsigned int src_id_type : 2; + unsigned int dst_id_len : 5; + unsigned int dst_id_type : 2; + unsigned int long_pad : 1; /* Set when maximum padding in packet */ + unsigned int users : 9; /* Reference counter */ + unsigned int padlen : 8; + + SilcUInt32 sequence; + SilcBuffer buffer; } SilcPacketContext; /****s* silccore/SilcPacketAPI/SilcPacketParserContext @@ -320,13 +332,36 @@ typedef bool (*SilcPacketParserCallback)(SilcPacketParserContext * * SOURCE */ -#define SILC_PACKET_LENGTH(__packet, __ret_truelen, __ret_paddedlen) \ -do { \ - SILC_GET16_MSB((__ret_truelen), (__packet)->data); \ - (__ret_paddedlen) = (__ret_truelen) + (__packet)->data[4]; \ +#define SILC_PACKET_LENGTH(__packetdata, __ret_truelen, __ret_paddedlen) \ +do { \ + SILC_GET16_MSB((__ret_truelen), (__packetdata)); \ + (__ret_paddedlen) = (__ret_truelen) + (SilcUInt8)(__packetdata)[4]; \ } while(0) /***/ +/****d* silccore/SilcPacketAPI/SILC_PACKET_DATALEN + * + * NAME + * + * #define SILC_PACKET_DATALEN ... + * + * DESCRIPTION + * + * Calculates the data length with given header length. This macro + * can be used to check whether the data_len with header_len exceeds + * SILC_PACKET_MAX_LEN. If it does, this returns the new data_len + * so that the SILC_PACKET_MAX_LEN is not exceeded. If the data_len + * plus header_len fits SILC_PACKET_MAX_LEN the returned data length + * is the data_len given as argument. This macro can be used when + * assembling packet. + * + * SOURCE + */ +#define SILC_PACKET_DATALEN(data_len, header_len) \ + ((data_len + header_len) > SILC_PACKET_MAX_LEN ? \ + data_len - ((data_len + header_len) - SILC_PACKET_MAX_LEN) : data_len) +/***/ + /****d* silccore/SilcPacketAPI/SILC_PACKET_PADLEN * * NAME @@ -335,14 +370,18 @@ do { \ * * DESCRIPTION * - * Returns the length of the padding in the packet. This is used + * Calculates the length of the padding in the packet. This is used * by various library routines to determine needed padding length. * * SOURCE */ -#define SILC_PACKET_PADLEN(__packetlen, __blocklen) \ - SILC_PACKET_DEFAULT_PADLEN - (__packetlen) % \ - ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN) +#define SILC_PACKET_PADLEN(__packetlen, __blocklen, __padlen) \ +do { \ + __padlen = (SILC_PACKET_DEFAULT_PADLEN - (__packetlen) % \ + ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN)); \ + if (__padlen < 8) \ + __padlen += ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN); \ +} while(0) /***/ /****d* silccore/SilcPacketAPI/SILC_PACKET_PADLEN_MAX @@ -354,13 +393,16 @@ do { \ * DESCRIPTION * * Returns the length of the padding up to the maximum length, which - * is 128 butes. This is used by various library routines to determine + * is 128 bytes. This is used by various library routines to determine * needed padding length. * * SOURCE */ -#define SILC_PACKET_PADLEN_MAX(__packetlen) \ - SILC_PACKET_MAX_PADLEN - (__packetlen) % SILC_PACKET_MAX_PADLEN +#define SILC_PACKET_PADLEN_MAX(__packetlen, __blocklen, __padlen) \ +do { \ + __padlen = (SILC_PACKET_MAX_PADLEN - (__packetlen) % \ + ((__blocklen) ? (__blocklen) : SILC_PACKET_DEFAULT_PADLEN)); \ +} while(0) /***/ /* Prototypes */ @@ -389,7 +431,7 @@ int silc_packet_send(SilcSocketConnection sock, bool force_send); * SYNOPSIS * * void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, - * SilcBuffer buffer, uint32 len); + * SilcBuffer buffer, SilcUInt32 len); * * DESCRIPTION * @@ -401,85 +443,73 @@ int silc_packet_send(SilcSocketConnection sock, bool force_send); * 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); /****f* silccore/SilcPacketAPI/silc_packet_assemble * * SYNOPSIS * - * void silc_packet_assemble(SilcPacketContext *ctx); + * bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng, + * SilcCipher cipher, SilcHmac hmac, + * SilcSocketConnection sock, + * const unsigned char *data, SilcUInt32 data_len, + * const SilcBuffer assembled_packet); * * DESCRIPTION * - * Assembles a new packet to be ready for send out. The buffer sent as - * argument must include the data to be sent and it must not be encrypted. - * The packet also must have enough free space so that the SILC header - * and padding maybe added to the packet. The packet is encrypted after - * this function has returned. - * - * The buffer sent as argument should be something like following: - * - * -------------------------------------------- - * | head | data | tail | - * -------------------------------------------- - * ^ ^ - * 58 bytes x bytes - * - * So that the SILC header and 1 - 16 bytes of padding can fit to - * the buffer. After assembly the buffer might look like this: - * - * -------------------------------------------- - * | data | | - * -------------------------------------------- - * ^ ^ - * Start of assembled packet - * - * Packet construct is as follows (* = won't be encrypted): - * - * n bytes SILC Header - * 2 bytes Payload length (*) - * 1 byte Flags - * 1 byte Packet type - * 2 bytes Source ID Length - * 2 bytes Destination ID Length - * 1 byte Source ID Type - * n bytes Source ID - * 1 byte Destination ID Type - * n bytes Destination ID - * - * 1 - 16 bytes Padding - * - * n bytes Data payload - * - * All fields in the packet will be authenticated by MAC. The MAC is - * not computed here, it must be computed separately before encrypting - * the packet. + * Assembles new packet to be ready for encrypting and sending out. + * The `packet' is filled by caller to include the packet header specific + * values. This prepares the socket connection's `sock' outoing buffer + * for sending data, and returns the assembled packet to the + * `assembled_packet' pointer sent by the caller. The `assembled_packet' + * is a reference to the socket connection's outgoing buffer. The + * returned packet can be encrypted, and then sent to network by calling + * silc_packet_send function. The `assembled_packet' may be freely + * modified (like encrypted etc.) but it must not be freed, since it is + * reference from `sock' outgoing buffer, and it is const. * ***/ -void silc_packet_assemble(SilcPacketContext *ctx, SilcCipher cipher); +bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng, + SilcCipher cipher, SilcHmac hmac, + SilcSocketConnection sock, + const unsigned char *data, SilcUInt32 data_len, + const SilcBuffer assembled_packet); /****f* silccore/SilcPacketAPI/silc_packet_send_prepare * * SYNOPSIS * - * void silc_packet_send_prepare(SilcSocketConnection sock, - * uint32 header_len, - * uint32 padlen, - * uint32 data_len); + * bool silc_packet_send_prepare(SilcSocketConnection sock, + * SilcUInt32 header_len, + * SilcUInt32 pad_len, + * SilcUInt32 data_len, + * SilcHmac hmac, + * const SilcBuffer packet); * * DESCRIPTION * - * Prepare outgoing data buffer for packet sending. This moves the data - * area so that new packet may be added into it. If needed this allocates - * more space to the buffer. This handles directly the connection's - * outgoing buffer in SilcSocketConnection object. + * This function can be used to prepare the outgoing data buffer in + * the socket connection specified by `sock' for packet sending. + * This is used internally by packet sending routines, but application + * may call this if it doesn't call silc_packet_assemble function. + * If that function is called then application must not call this since + * that function calls this internally. + * + * This returns the prepared data area into the `packet' pointer provided + * caller, which can be used then to add data to it, and later encrypt + * it. The `packet' includes reference to the socket connection's + * outgoing buffer. The `packet' may be freely modified (like + * encrypted etc.) but it must not be freed, since it is reference from + * `sock' outgoing buffer, and it is const. * ***/ -void silc_packet_send_prepare(SilcSocketConnection sock, - uint32 header_len, - uint32 padlen, - uint32 data_len); +bool silc_packet_send_prepare(SilcSocketConnection sock, + SilcUInt32 header_len, + SilcUInt32 pad_len, + SilcUInt32 data_len, + SilcHmac hmac, + const SilcBuffer packet); /****f* silccore/SilcPacketAPI/silc_packet_receive * @@ -503,7 +533,7 @@ int silc_packet_receive(SilcSocketConnection sock); * * SYNOPSIS * - * void silc_packet_receive_process(SilcSocketConnection sock, + * bool silc_packet_receive_process(SilcSocketConnection sock, * bool local_is_router, * SilcCipher cipher, SilcHmac hmac, * SilcPacketParserCallback parser, @@ -511,7 +541,7 @@ int silc_packet_receive(SilcSocketConnection sock); * * DESCRIPTION * - * Processes and decrypts the incmoing data, and calls parser callback + * Processes and decrypts the incoming data, and calls parser callback * for each received packet that will handle the actual packet parsing. * If more than one packet was received this calls the parser multiple * times. The parser callback will get context SilcPacketParserContext @@ -525,10 +555,10 @@ int silc_packet_receive(SilcSocketConnection sock); * 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);