1 /* 2 3 silcpacket.h 4 5 Author: Pekka Riikonen <priikone@silcnet.org> 6 7 Copyright (C) 1997 - 2014 Pekka Riikonen 8 9 The contents of this file are subject to one of the Licenses specified 10 in the COPYING file; You may not use this file except in compliance 11 with the License. 12 13 The software distributed under the License is distributed on an "AS IS" 14 basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY 15 KIND, either expressed or implied. See the COPYING file for more 16 information. 17 18 */ 19 20 /****h* silccore/SILC Packet Engine Interface 21 * 22 * DESCRIPTION 23 * 24 * The SILC secure binary packet protocol interface, provides interface for 25 * sending and receiving SILC packets. The interface provides a packet 26 * engine, that can be used to receive packets from packet streams, and 27 * routines for sending all kinds of SILC packets. 28 * 29 * The packet engine and packet stream are thread safe. They can be safely 30 * used in multi threaded environment. 31 * 32 ***/ 33 34 #ifndef SILCPACKET_H 35 #define SILCPACKET_H 36 37 /* Maximum packet length */ 38 #define SILC_PACKET_MAX_LEN 0xffff 39 40 /* Maximum length of ID */ 41 #define SILC_PACKET_MAX_ID_LEN 28 42 43 /****d* silccore/SilcPacketAPI/SilcPacketType 44 * 45 * NAME 46 * 47 * typedef SilcUInt8 SilcPacketType; 48 * 49 * DESCRIPTION 50 * 51 * SILC packet type definition and all the packet types. 52 * 53 * SOURCE 54 */ 55 typedef SilcUInt8 SilcPacketType; 56 57 /* SILC Packet types. */ 58 #define SILC_PACKET_DISCONNECT 1 /* Disconnection */ 59 #define SILC_PACKET_SUCCESS 2 /* Success */ 60 #define SILC_PACKET_FAILURE 3 /* Failure */ 61 #define SILC_PACKET_REJECT 4 /* Rejected */ 62 #define SILC_PACKET_NOTIFY 5 /* Notify message */ 63 #define SILC_PACKET_ERROR 6 /* Error message */ 64 #define SILC_PACKET_CHANNEL_MESSAGE 7 /* Message for channel */ 65 #define SILC_PACKET_CHANNEL_KEY 8 /* Key of the channel */ 66 #define SILC_PACKET_PRIVATE_MESSAGE 9 /* Private message */ 67 #define SILC_PACKET_PRIVATE_MESSAGE_KEY 10 /* Private message key*/ 68 #define SILC_PACKET_COMMAND 11 /* Command */ 69 #define SILC_PACKET_COMMAND_REPLY 12 /* Reply to a command */ 70 #define SILC_PACKET_KEY_EXCHANGE 13 /* Start of KE */ 71 #define SILC_PACKET_KEY_EXCHANGE_1 14 /* KE1 */ 72 #define SILC_PACKET_KEY_EXCHANGE_2 15 /* KE2 */ 73 #define SILC_PACKET_CONNECTION_AUTH_REQUEST 16 /* Request of auth meth */ 74 #define SILC_PACKET_CONNECTION_AUTH 17 /* Connectinon auth */ 75 #define SILC_PACKET_NEW_ID 18 /* Sending new ID */ 76 #define SILC_PACKET_NEW_CLIENT 19 /* Client registering */ 77 #define SILC_PACKET_NEW_SERVER 20 /* Server registering */ 78 #define SILC_PACKET_NEW_CHANNEL 21 /* Channel registering */ 79 #define SILC_PACKET_REKEY 22 /* Re-key start */ 80 #define SILC_PACKET_REKEY_DONE 23 /* Re-key done */ 81 #define SILC_PACKET_HEARTBEAT 24 /* Heartbeat */ 82 #define SILC_PACKET_KEY_AGREEMENT 25 /* Key Agreement request */ 83 #define SILC_PACKET_RESUME_ROUTER 26 /* Backup router resume */ 84 #define SILC_PACKET_FTP 27 /* File Transfer */ 85 #define SILC_PACKET_RESUME_CLIENT 28 /* Client resume */ 86 #define SILC_PACKET_ACK 29 /* Acknowledgement */ 87 88 #define SILC_PACKET_PRIVATE 200 /* Private range start */ 89 #define SILC_PACKET_MAX 255 /* RESERVED */ 90 91 #define SILC_PACKET_NONE 0 /* RESERVED */ 92 #define SILC_PACKET_ANY 0 93 /***/ 94 95 /****d* silccore/SilcPacketAPI/SilcPacketFlags 96 * 97 * NAME 98 * 99 * typedef SilcUInt8 SilcPacketFlags; 100 * 101 * DESCRIPTION 102 * 103 * SILC packet flags type definition and all the packet flags. 104 * 105 * SOURCE 106 */ 107 typedef SilcUInt8 SilcPacketFlags; 108 109 /* All defined packet flags */ 110 #define SILC_PACKET_FLAG_NONE 0x00 /* No flags */ 111 #define SILC_PACKET_FLAG_PRIVMSG_KEY 0x01 /* Private message key */ 112 #define SILC_PACKET_FLAG_LIST 0x02 /* Packet is a list */ 113 #define SILC_PACKET_FLAG_BROADCAST 0x04 /* Packet is a broadcast */ 114 #define SILC_PACKET_FLAG_COMPRESSED 0x08 /* Payload is compressed */ 115 #define SILC_PACKET_FLAG_ACK 0x10 /* Acknowledge packet */ 116 117 /* Impelemntation specific flags */ 118 #define SILC_PACKET_FLAG_LONG_PAD 0x20 /* Use maximum padding */ 119 /***/ 120 121 /****s* silccore/SilcPacketAPI/SilcPacketEngine 122 * 123 * NAME 124 * 125 * typedef struct SilcPacketEngineStruct *SilcPacketEngine; 126 * 127 * DESCRIPTION 128 * 129 * The packet engine context, allocated by silc_packet_engine_start. 130 * The engine is destroyed with silc_packet_engine_stop. 131 * 132 ***/ 133 typedef struct SilcPacketEngineStruct *SilcPacketEngine; 134 135 /****s* silccore/SilcPacketAPI/SilcPacketStream 136 * 137 * NAME 138 * 139 * typedef struct SilcPacketStreamStruct *SilcPacketStream; 140 * 141 * DESCRIPTION 142 * 143 * The packet stream context, allocated by silc_packet_stream_create. 144 * The stream is destroyed with silc_packet_stream_destroy. 145 * 146 ***/ 147 typedef struct SilcPacketStreamStruct *SilcPacketStream; 148 149 /****s* silccore/SilcPacketAPI/SilcPacket 150 * 151 * NAME 152 * 153 * typedef struct SilcPacketStruct *SilcPacket; 154 * 155 * DESCRIPTION 156 * 157 * The SilcPacket is returned by the packet engine in the SilcPacketReceive 158 * callback. The application can parse the data payload from the 159 * SilcPacket. Also packet type, flags, and sender and destination 160 * IDs are available. The application must free the packet with the 161 * silc_packet_free function if it takes it in for processing. 162 * 163 * The `buffer' field contains the parsed packet payload and the start 164 * of the data area will point to the start of the packet payload. 165 * 166 * The list pointer `next' can be used by the application to put the 167 * packet context in a list during processing, if needed. 168 * 169 * SOURCE 170 */ 171 typedef struct SilcPacketStruct { 172 struct SilcPacketStruct *next; /* List pointer, application may set */ 173 SilcPacketStream stream; /* Packet stream this packet is from */ 174 SilcBufferStruct buffer; /* Packet data payload */ 175 unsigned char *src_id; /* Source ID */ 176 unsigned char *dst_id; /* Destination ID */ 177 unsigned int src_id_len : 6; /* Source ID length */ 178 unsigned int src_id_type : 2; /* Source ID type */ 179 unsigned int dst_id_len : 6; /* Destination ID length */ 180 unsigned int dst_id_type : 2; /* Destination ID type */ 181 SilcPacketType type; /* Packet type */ 182 SilcPacketFlags flags; /* Packet flags */ 183 } *SilcPacket; 184 /***/ 185 186 /****d* silcutil/SilcPacketAPI/SilcPacketError 187 * 188 * NAME 189 * 190 * typedef enum { ... } SilcPacketError 191 * 192 * DESCRIPTION 193 * 194 * Packet errors. This is returned in the error callback. If application 195 * needs the actual lower level stream error, it needs to retrieve it 196 * from the actual stream. It can retrieve the underlaying stream from 197 * the packet stream by calling silc_packet_stream_get_stream function. 198 * 199 * You may retrieve string version of the SilcPacketError by calling 200 * silc_packet_error_string. 201 * 202 * SOURCE 203 */ 204 typedef enum { 205 SILC_PACKET_ERR_READ, /* Error while reading */ 206 SILC_PACKET_ERR_WRITE, /* Error while writing */ 207 SILC_PACKET_ERR_MAC_FAILED, /* Packet MAC check failed */ 208 SILC_PACKET_ERR_DECRYPTION_FAILED, /* Packet decryption failed */ 209 SILC_PACKET_ERR_UNKNOWN_SID, /* Unknown SID (with IV included) */ 210 SILC_PACKET_ERR_MALFORMED, /* Packet is malformed */ 211 SILC_PACKET_ERR_NO_MEMORY, /* System out of memory */ 212 } SilcPacketError; 213 /***/ 214 215 /****f* silccore/SilcPacketAPI/SilcPacketReceiveCb 216 * 217 * SYNOPSIS 218 * 219 * typedef SilcBool (*SilcPacketReceiveCb)(SilcPacketEngine engine, 220 * SilcPacketStream stream, 221 * SilcPacket packet, 222 * void *callback_context, 223 * void *stream_context); 224 * 225 * DESCRIPTION 226 * 227 * The packet receive callback is called by the packet engine when a new 228 * SILC Packet has arrived. The application must free the returned 229 * SilcPacket with silc_packet_free if it takes the packet in for 230 * processing. This callback is set in the SilcPacketCallbacks structure. 231 * The `callback_context' is the context set as argument in the 232 * silc_packet_engine_start function. The `stream_context' is stream 233 * specific context that was set by calling silc_packet_set_context. 234 * 235 * If the application takes the received packet `packet' into processing 236 * TRUE must be returned. If FALSE is returned the packet engine will 237 * pass the packet to other packet processor, if one has been linked 238 * to the stream with silc_packet_stream_link function. If no extra 239 * processor is linked the packet is dropped. 240 * 241 * EXAMPLE 242 * 243 * SilcBool 244 * silc_foo_packet_receive_cb(SilcPacketEngine engine, 245 * SilcPacketStream stream, SilcPacket packet, 246 * void *callback_context, void *stream_context) 247 * { 248 * Application ctx = callback_context; 249 * 250 * // If we're not up yet, let's not process the packet 251 * if (ctx->initialized == FALSE) 252 * return FALSE; 253 * 254 * // Process the incoming packet... 255 * ... 256 * 257 * // It's our packet now, no one else will get it 258 * return TRUE; 259 * } 260 * 261 ***/ 262 typedef SilcBool (*SilcPacketReceiveCb)(SilcPacketEngine engine, 263 SilcPacketStream stream, 264 SilcPacket packet, 265 void *callback_context, 266 void *stream_context); 267 268 /****f* silccore/SilcPacketAPI/SilcPacketEosCb 269 * 270 * SYNOPSIS 271 * 272 * typedef void (*SilcPacketEosCb)(SilcPacketEngine engine, 273 * SilcPacketStream stream, 274 * void *callback_context, 275 * void *stream_context); 276 * 277 * DESCRIPTION 278 * 279 * The End Of Stream (EOS) callback, that is called by the packet engine 280 * when the underlaying stream has ended. No more data can be sent to 281 * the stream or read from it. The `stream' must be destroyed by 282 * calling the silc_packet_stream_destroy. This callback is set in the 283 * SilcPacketCallbacks structure. 284 * 285 ***/ 286 typedef void (*SilcPacketEosCb)(SilcPacketEngine engine, 287 SilcPacketStream stream, 288 void *callback_context, 289 void *stream_context); 290 291 /****f* silccore/SilcPacketAPI/SilcPacketErrorCb 292 * 293 * SYNOPSIS 294 * 295 * typedef void (*SilcPacketErrorCb)(SilcPacketEngine engine, 296 * SilcPacketStream stream, 297 * SilcPacketError error, 298 * void *callback_context, 299 * void *stream_context); 300 * 301 * DESCRIPTION 302 * 303 * The error callback that is called by the packet engine if an error 304 * occurs. The `error' will indicate the error. This callback is set 305 * in the SilcPacketCallbacks structure. 306 * 307 ***/ 308 typedef void (*SilcPacketErrorCb)(SilcPacketEngine engine, 309 SilcPacketStream stream, 310 SilcPacketError error, 311 void *callback_context, 312 void *stream_context); 313 314 /****s* silccore/SilcPacketAPI/SilcPacketCallbacks 315 * 316 * NAME 317 * 318 * typedef struct { ... } *SilcPacketCallbacks; 319 * 320 * DESCRIPTION 321 * 322 * This structure is sent as argument to the silc_packet_engine_start 323 * function to set the callback functions for the packet engine. The 324 * packet engine will call the callbacks when necessary. Application 325 * must always be provided for the packet engine. 326 * 327 * SOURCE 328 */ 329 typedef struct { 330 SilcPacketReceiveCb packet_receive; /* Called when packet is received */ 331 SilcPacketEosCb eos; /* Called on end of stream */ 332 SilcPacketErrorCb error; /* Called on an error */ 333 } SilcPacketCallbacks; 334 /***/ 335 336 /* Prototypes */ 337 338 /****f* silccore/SilcPacketAPI/silc_packet_engine_start 339 * 340 * SYNOPSIS 341 * 342 * SilcPacketEngine 343 * silc_packet_engine_start(SilcRng rng, SilcBool router, 344 * SilcPacketCallbacks *callbacks, 345 * void *callback_context); 346 * 347 * DESCRIPTION 348 * 349 * Create new packet engine for processing incoming and outgoing packets. 350 * If `router' is TRUE then the application is considered to be router 351 * server, and certain packets are handled differently. Client and normal 352 * server must set it to FALSE. The `callbacks' is a SilcPacketCallbacks 353 * structure provided by the caller which includes the callbacks that is 354 * called when for example packet is received, or end of stream is called. 355 * 356 * NOTES 357 * 358 * The packet engine is thread safe. You can use one packet engine in 359 * multi threaded application. 360 * 361 ***/ 362 SilcPacketEngine 363 silc_packet_engine_start(SilcRng rng, SilcBool router, 364 const SilcPacketCallbacks *callbacks, 365 void *callback_context); 366 367 /****f* silccore/SilcPacketAPI/silc_packet_engine_stop 368 * 369 * SYNOPSIS 370 * 371 * void silc_packet_engine_stop(SilcPacketEngine engine); 372 * 373 * DESCRIPTION 374 * 375 * Stop the packet engine. No new packets can be sent or received after 376 * calling this, and the `engine' will become invalid. 377 * 378 ***/ 379 void silc_packet_engine_stop(SilcPacketEngine engine); 380 381 /****f* silccore/SilcPacketAPI/silc_packet_error_string 382 * 383 * SYNOPSIS 384 * 385 * const char *silc_packet_error_string(SilcPacketError error); 386 * 387 * DESCRIPTION 388 * 389 * Return the packet error as string. 390 * 391 ***/ 392 const char *silc_packet_error_string(SilcPacketError error); 393 394 /****f* silccore/SilcPacketAPI/silc_packet_engine_get_streams 395 * 396 * SYNOPSIS 397 * 398 * SilcDList silc_packet_engine_get_streams(SilcPacketEngine engine); 399 * 400 * DESCRIPTION 401 * 402 * Returns list of packet streams added to the packet engine. The caller 403 * must free the list with silc_packet_engine_free_streams_list. 404 * 405 * NOTES 406 * 407 * This function may also return disconnected and destroyed streams. The 408 * caller should use silc_packet_stream_is_valid to check if the stream 409 * is valid. 410 * 411 ***/ 412 SilcDList silc_packet_engine_get_streams(SilcPacketEngine engine); 413 414 /****f* silccore/SilcPacketAPI/silc_packet_engine_free_streams_list 415 * 416 * SYNOPSIS 417 * 418 * void silc_packet_engine_free_streams_list(SilcDList streams); 419 * 420 * DESCRIPTION 421 * 422 * Free's the streams list returned by silc_packet_engine_get_streams. 423 * 424 ***/ 425 void silc_packet_engine_free_streams_list(SilcDList streams); 426 427 /****f* silccore/SilcPacketAPI/silc_packet_stream_create 428 * 429 * SYNOPSIS 430 * 431 * SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, 432 * SilcSchedule schedule, 433 * SilcStream stream); 434 * 435 * DESCRIPTION 436 * 437 * Create new packet stream and use the `stream' as underlaying stream. 438 * Usually the `stream' would be a socket stream, but it can be any 439 * stream. After this function returns, packets can immediately be 440 * sent to and received from the stream. 441 * 442 * The `stream' will be owned by the packet stream and will be closed 443 * and destroyed when the packet stream is destroyed. If the packet 444 * stream creation fails the `stream' is left intact. 445 * 446 * NOTES 447 * 448 * SilcPacketStream cannot be used with silc_stream_* routines (such as 449 * silc_stream_read and silc_stream_write) because of its special nature. 450 * Use the silc_packet_send and the silc_packet_send_ext to send packets. 451 * To read packets you will receive the packet receive callback from 452 * packet engine. Destroy the stream with silc_packet_stream_destroy. 453 * 454 * The SilcPacketStream is thread safe. Same context can be safely used 455 * in multi threaded environment. 456 * 457 ***/ 458 SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, 459 SilcSchedule schedule, 460 SilcStream stream); 461 462 /****f* silccore/SilcPacketAPI/silc_packet_stream_add_remote 463 * 464 * SYNOPSIS 465 * 466 * SilcPacketStream silc_packet_stream_add_remote(SilcPacketStream stream, 467 * const char *remote_ip, 468 * SilcUInt16 remote_port, 469 * SilcPacket packet); 470 * 471 * DESCRIPTION 472 * 473 * This function is used to add remote receivers in packet stream `stream' 474 * that has UDP/IP socket stream as the underlaying stream. This function 475 * cannot be used with other type of streams. This returns new packet 476 * stream context that can be used to send to and receive packets from 477 * the specified remote IP and remote port, or NULL on error. The `stream' 478 * is the actual stream that is used to send and receive the data. 479 * 480 * When the parent `stream' receives packets from remote IP address 481 * and port that does not have its own remote packet stream, it returns 482 * the packet to the packet callback set for `stream'. The sender's 483 * IP address and port can then be retrieved by using the 484 * silc_packet_get_sender function and to create new packet stream by 485 * calling this function. After that, all packets from that IP address 486 * and port will be received by the new packet stream. 487 * 488 * If the `packet' is non-NULL it will be injected into the new packet 489 * stream as soon as the scheduler associated with `stream' schedules 490 * new tasks. It can be used to inject an incoming packet to the stream. 491 * 492 * This interface is for connectionless UDP streams. If it is possible 493 * to create connected stream it should be done for performance reasons. 494 * 495 * EXAMPLE 496 * 497 * // Create parent packet stream, it can receive packets from anywhere 498 * listener = silc_net_udp_connect("0.0.0.0", 500, NULL, 0, schedule); 499 * parent = silc_packet_stream_create(engine, schedule, listener); 500 * 501 * ... 502 * // Received a packet to the parent stream, get the sender information. 503 * silc_packet_get_sender(packet, &ip, &port); 504 * 505 * // Create new packet stream for this remote location. 506 * remote = silc_packet_stream_add_remote(parent, ip, port, packet); 507 * 508 ***/ 509 SilcPacketStream silc_packet_stream_add_remote(SilcPacketStream stream, 510 const char *remote_ip, 511 SilcUInt16 remote_port, 512 SilcPacket packet); 513 514 /****f* silccore/SilcPacketAPI/silc_packet_stream_inject 515 * 516 * SYNOPSIS 517 * 518 * SilcBool silc_packet_stream_inject(SilcPacketStream stream, 519 * SilcPacket packet); 520 * 521 * DESCRIPTION 522 * 523 * This function can be used to inject the `packet' to the given 524 * packet `stream'. The packet will appear in the packet stream's 525 * packet handler(s). If this returns FALSE the packet was not 526 * injected. 527 * 528 ***/ 529 SilcBool silc_packet_stream_inject(SilcPacketStream stream, 530 SilcPacket packet); 531 532 /****f* silccore/SilcPacketAPI/silc_packet_stream_destroy 533 * 534 * SYNOPSIS 535 * 536 * void silc_packet_stream_destroy(SilcPacketStream stream); 537 * 538 * DESCRIPTION 539 * 540 * Destroy packet stream and the underlaying stream. This will also 541 * close and destroy the underlaying stream. 542 * 543 ***/ 544 void silc_packet_stream_destroy(SilcPacketStream stream); 545 546 /****f* silccore/SilcPacketAPI/silc_packet_stream_is_valid 547 * 548 * SYNOPSIS 549 * 550 * SilcBool silc_packet_stream_is_valid(SilcPacketStream stream); 551 * 552 * DESCRIPTION 553 * 554 * Returns TRUE if the packet stream indicated by `stream' is valid and 555 * has not been disconnected or destroyed. 556 * 557 ***/ 558 SilcBool silc_packet_stream_is_valid(SilcPacketStream stream); 559 560 /****f* silccore/SilcPacketAPI/silc_packet_stream_set_router 561 * 562 * SYNOPSIS 563 * 564 * void silc_packet_stream_set_router(SilcPacketStream stream); 565 * 566 * DESCRIPTION 567 * 568 * When called sets the stream indicates by `stream' as SILC router 569 * connection stream. This causes that certain packets are handled 570 * differently. This must be called for router connection streams and 571 * must not be called for any other stream. 572 * 573 ***/ 574 void silc_packet_stream_set_router(SilcPacketStream stream); 575 576 /****f* silccore/SilcPacketAPI/silc_packet_stream_set_iv_included 577 * 578 * SYNOPSIS 579 * 580 * void silc_packet_stream_set_iv_included(SilcPacketStream stream); 581 * 582 * DESCRIPTION 583 * 584 * Sets an IV Included property for the stream indicated by `stream'. 585 * This means that the IV used in the encryption will be included in 586 * the resulted ciphertext. This makes it possible to send and receive 587 * packets on unreliable network transport protocol, such as UDP/IP. 588 * This must be called if the underlaying stream in the `stream' is UDP 589 * stream. 590 * 591 * When this is set to the stream the silc_packet_set_sid must be called 592 * to set new Security ID. The Security ID will be included with the IV 593 * in the ciphertext. 594 * 595 ***/ 596 void silc_packet_stream_set_iv_included(SilcPacketStream stream); 597 598 /****f* silccore/SilcPacketAPI/silc_packet_stream_set_stream 599 * 600 * SYNOPSIS 601 * 602 * void silc_packet_stream_set_stream(SilcPacketStream packet_stream, 603 * SilcStream stream); 604 * 605 * DESCRIPTION 606 * 607 * This function may be used to change the underlaying stream in the 608 * packet stream indicated by `packet_stream'. Note that the old 609 * stream will not be used after calling this function. The caller is 610 * responsible destroying the old stream. The `stream' will use 611 * the same scheduler as the `packet_stream'. 612 * 613 ***/ 614 void silc_packet_stream_set_stream(SilcPacketStream packet_stream, 615 SilcStream stream); 616 617 /****f* silccore/SilcPacketAPI/silc_packet_stream_get_stream 618 * 619 * SYNOPSIS 620 * 621 * SilcStream silc_packet_stream_get_stream(SilcPacketStream stream); 622 * 623 * DESCRIPTION 624 * 625 * Returns the actual stream that is associated with the packet stream 626 * `stream'. The caller must not free the returned stream. The returned 627 * stream is the same pointer that was set for silc_packet_stream_create. 628 * This function could be used for example when an error callback is 629 * called by the packet engine to retrieve the actual lower level error 630 * from the stream. 631 * 632 ***/ 633 SilcStream silc_packet_stream_get_stream(SilcPacketStream stream); 634 635 /****f* silccore/SilcPacketAPI/silc_packet_stream_link 636 * 637 * SYNOPSIS 638 * 639 * SilcBool silc_packet_stream_link(SilcPacketStream stream, 640 * SilcPacketCallbacks *callbacks, 641 * void *callback_context, 642 * int priority, ...); 643 * 644 * DESCRIPTION 645 * 646 * Links the packet processing callbacks indicated by `callbacks' into 647 * the packet stream indicated by `stream' with priority `priority' for 648 * the packet types given in the variable argument list. This function 649 * can be used to link to the packet stream for specific packet types 650 * and receive them in the specified callbacks. This way, a third party, 651 * for example some library may attach itself into the packet stream 652 * and receive and process certain packets. The variable argument 653 * list is ended with -1. To link to receive all packets use 654 * SILC_PACKET_ANY. 655 * 656 * The default packet processing callbacks given as argument to the 657 * silc_packet_engine_start has the priority 0. Any priority higher 658 * than 0 will then take precedence over the default callbacks. Any 659 * priority lower than 0 (negative value) will be processed after the 660 * default callbacks. 661 * 662 * Note that setting only the 'packet_receive' callback in the `callbacks' 663 * is required. 664 * 665 * EXAMPLE 666 * 667 * // Link to this packet stream, with high priority, for 668 * // SILC_PACKET_CONNECTION_AUTH and SILC_PACKET_CONNECTION_AUTH_REQUEST 669 * // packets. We don't care about other packets. 670 * silc_packet_stream_link(stream, our_callbacks, our_context, 671 * 1000000, SILC_PACKET_CONNECTION_AUTH, 672 * SILC_PACKET_CONNECTION_AUTH_REQUEST, -1); 673 * 674 ***/ 675 SilcBool silc_packet_stream_link(SilcPacketStream stream, 676 const SilcPacketCallbacks *callbacks, 677 void *callback_context, 678 int priority, ...); 679 680 /****f* silccore/SilcPacketAPI/silc_packet_stream_unlink 681 * 682 * SYNOPSIS 683 * 684 * void silc_packet_stream_unlink(SilcPacketStream stream, 685 * SilcPacketCallbacks *callbacks, 686 * void *callback_context); 687 * 688 * DESCRIPTION 689 * 690 * Unlinks the `callbacks' with `callback_context' from the packet stream 691 * indicated by `stream'. This function must be called for the callbacks 692 * that was linked to `stream' when they are not needed anymore. 693 * 694 ***/ 695 void silc_packet_stream_unlink(SilcPacketStream stream, 696 const SilcPacketCallbacks *callbacks, 697 void *callback_context); 698 699 /****f* silccore/SilcPacketAPI/SilcPacketWrapCoder 700 * 701 * SYNOPSIS 702 * 703 * typedef SilcBool (*SilcPacketWrapCoder)(SilcStream stream, 704 * SilcStreamStatus status, 705 * SilcBuffer buffer, 706 * void *context); 707 * 708 * DESCRIPTION 709 * 710 * The encoder/decoder callback for silc_packet_stream_wrap. 711 * 712 * If the `status' is SILC_STREAM_CAN_WRITE then additional data can 713 * be added to `buffer' which contains the data that is being written 714 * to the stream. There is at least 16 bytes of free space in head 715 * space of the buffer in case new headers need to be added. 716 * The silc_buffer_enlarge should be called to verify that there is 717 * enough room before adding data to it. The `buffer' must not be freed. 718 * If the return value is FALSE the encoding failed and the packet is 719 * not sent at all and the stream will receive error. Return TRUE if 720 * the encoding succeeded. 721 * 722 * If the `status' is SILC_STREAM_CAN_READ then data from the `buffer' 723 * may be read before it is passed to reader when silc_stream_read is 724 * called. The `buffer' may be advanced also to hide data in it. If 725 * return value is FALSE the decoding failed (or the packet is ignored) 726 * and the packet will not be processed by the wrapped packet stream. 727 * If there are other packet streams wanting the same packet, they will 728 * get it, and if not the packet will drop. Return TRUE if decoding 729 * succeeded. 730 * 731 ***/ 732 typedef SilcBool (*SilcPacketWrapCoder)(SilcStream stream, 733 SilcStreamStatus status, 734 SilcBuffer buffer, 735 void *context); 736 737 /****f* silccore/SilcPacketAPI/silc_packet_stream_wrap 738 * 739 * SYNOPSIS 740 * 741 * SilcStream silc_packet_stream_wrap(SilcPacketStream stream, 742 * SilcPacketType type, 743 * SilcPacketFlags flags, 744 * SilcBool blocking_mode, 745 * SilcIdType src_id_type, void *src_id, 746 * SilcIdType dst_id_type, void *dst_id, 747 * SilcPacketWrapCoder coder, 748 * void *context); 749 * 750 * DESCRIPTION 751 * 752 * Wraps the packet stream indicated by `stream' into a SilcStream for 753 * the packet type indicated by `type' with packet flags indicated by 754 * `flags'. The returned SilcStream can be used to read and write the 755 * specified SILC packets with the specified packet flags, by calling 756 * silc_stream_read and silc_stream_write, respectively. The returned 757 * stream can be destroyed by calling silc_stream_destroy. It does not 758 * destroy the wrapped packet stream. 759 * 760 * If the `blocking_mode' mode is TRUE then the silc_stream_read and 761 * silc_stream_write may block the calling process or thread until SILC 762 * packet is read or written. If it is FALSE the stream is in non-blocking 763 * mode and the calls never block. The returned stream is thread-safe and 764 * packets may be read and written in multi-threaded environment. 765 * 766 * In non-blocking mode the silc_stream_set_notifier must be called before 767 * the returned stream can be used to read packets. The stream status 768 * SILC_STREAM_CAN_READ will be returned to the notifier callback to 769 * indicate that a packet is ready for reading. Calling silc_stream_read 770 * once returns one complete SILC packet data payload (which is of type of 771 * `type'). 772 * 773 * If src_id and/or dst_id are set they will be used as the ids in the 774 * sent SILC packets. If the dst_id is set then the stream will receive 775 * packets only originating from that id. 776 * 777 * The `coder' is optional encoder/decoder callback which the packet engine 778 * will call if it is non-NULL. It can be used to encode additional data 779 * into each packet when silc_stream_write is called or decode data before 780 * it is passed to reader when silc_stream_read is called. The `context' 781 * is passed to `coder'. 782 * 783 * The returned SilcStream can be used as any normal stream and all 784 * SilcStream API functions may be used with the stream. This returns 785 * NULL on error. 786 * 787 ***/ 788 SilcStream silc_packet_stream_wrap(SilcPacketStream stream, 789 SilcPacketType type, 790 SilcPacketFlags flags, 791 SilcBool blocking_mode, 792 SilcIdType src_id_type, void *src_id, 793 SilcIdType dst_id_type, void *dst_id, 794 SilcPacketWrapCoder coder, 795 void *context); 796 797 /****f* silccore/SilcPacketAPI/silc_packet_stream_is_udp 798 * 799 * SYNOPSIS 800 * 801 * SilcBool silc_packet_stream_is_udp(SilcPacketStream stream); 802 * 803 * DESCRIPTION 804 * 805 * Returns TRUE if the packet stream indicated by `stream' is using 806 * UDP transport. 807 * 808 ***/ 809 SilcBool silc_packet_stream_is_udp(SilcPacketStream stream); 810 811 /****f* silccore/SilcPacketAPI/silc_packet_get_sender 812 * 813 * SYNOPSIS 814 * 815 * SilcBool silc_packet_get_sender(SilcPacket packet, 816 * const char **sender_ip, 817 * SilcUInt16 *sender_port); 818 * 819 * DESCRIPTION 820 * 821 * Returns the packet sender's IP address and port from UDP packet 822 * indicated by `packet'. This can be called only from the packet 823 * callback to retrieve the information of the packet's sender. Returns 824 * FALSE if the information is not available. 825 * 826 ***/ 827 SilcBool silc_packet_get_sender(SilcPacket packet, 828 const char **sender_ip, 829 SilcUInt16 *sender_port); 830 831 /****f* silccore/SilcPacketAPI/silc_packet_stream_ref 832 * 833 * SYNOPSIS 834 * 835 * void silc_packet_stream_ref(SilcPacketStream stream); 836 * 837 * DESCRIPTION 838 * 839 * Increase reference counter for the stream indicated by `stream'. This 840 * can be used to take a reference for the stream. To unreference the 841 * stream call silc_packet_stream_unref function. 842 * 843 ***/ 844 void silc_packet_stream_ref(SilcPacketStream stream); 845 846 /****f* silccore/SilcPacketAPI/silc_packet_stream_unref 847 * 848 * SYNOPSIS 849 * 850 * void silc_packet_stream_unref(SilcPacketStream stream); 851 * 852 * DESCRIPTION 853 * 854 * Decrease reference counter for the stream indicated by `stream'. If 855 * the counter hits zero the stream will be destroyed automatically. 856 * 857 ***/ 858 void silc_packet_stream_unref(SilcPacketStream stream); 859 860 /****f* silccore/SilcPacketAPI/silc_packet_get_engine 861 * 862 * SYNOPSIS 863 * 864 * SilcPacketEngine silc_packet_get_engine(SilcPacketStream stream); 865 * 866 * DESCRIPTION 867 * 868 * Returns the packet engine from the `stream'. 869 * 870 ***/ 871 SilcPacketEngine silc_packet_get_engine(SilcPacketStream stream); 872 873 /****f* silccore/SilcPacketAPI/silc_packet_set_context 874 * 875 * SYNOPSIS 876 * 877 * void silc_packet_set_context(SilcPacketStream stream, 878 * void *stream_context); 879 * 880 * DESCRIPTION 881 * 882 * Sets a stream specific context to the stream. The context will 883 * be delivered to all callback functions, and it can be retrieved by 884 * calling silc_packet_get_context function as well. Note that this is 885 * separate packet stream specific context, and not the same as 886 * `callback_context' in silc_packet_engine_start. Both will be delivered 887 * to the callbacks, and this context as the `stream_context' argument. 888 * 889 ***/ 890 void silc_packet_set_context(SilcPacketStream stream, void *stream_context); 891 892 /****f* silccore/SilcPacketAPI/silc_packet_get_context 893 * 894 * SYNOPSIS 895 * 896 * void *silc_packet_get_context(SilcPacketStream stream); 897 * 898 * DESCRIPTION 899 * 900 * Returns the current set application context, or NULL if none is set. 901 * 902 ***/ 903 void *silc_packet_get_context(SilcPacketStream stream); 904 905 /****f* silccore/SilcPacketAPI/silc_packet_set_keys 906 * 907 * SYNOPSIS 908 * 909 * void silc_packet_set_keys(SilcPacketStream stream, SilcCipher send_key, 910 * SilcCipher receive_key, SilcHmac send_hmac, 911 * SilcHmac receive_hmac, SilcBool rekey); 912 * 913 * DESCRIPTION 914 * 915 * Set ciphers and HMACs to be used to encrypt sent packets, and decrypt 916 * received packets. This can be called multiple times to change the 917 * ciphers and HMACs. 918 * 919 * If the `rekey' is TRUE this function will send SILC_PACKET_REKEY_DONE 920 * to the `stream' and will set the new keys. If it is FALSE the keys 921 * are changed but the packet is not changed. 922 * 923 * When changing keys the old cipher and HMACs will be freed. If the keys 924 * are not set at all, packets will not be encrypted or decrypted. 925 * 926 ***/ 927 SilcBool silc_packet_set_keys(SilcPacketStream stream, SilcCipher send_key, 928 SilcCipher receive_key, SilcHmac send_hmac, 929 SilcHmac receive_hmac, SilcBool rekey); 930 931 /****f* silccore/SilcPacketAPI/silc_packet_get_keys 932 * 933 * SYNOPSIS 934 * 935 * SilcBool silc_packet_get_keys(SilcPacketStream stream, 936 * SilcCipher *send_key, 937 * SilcCipher *receive_key, 938 * SilcHmac *send_hmac, 939 * SilcHmac *receive_hmac); 940 * 941 * DESCRIPTION 942 * 943 * Returns the pointers of current ciphers and HMACs from the `stream'. 944 * Returns FALSE if keys are not set. 945 * 946 ***/ 947 SilcBool silc_packet_get_keys(SilcPacketStream stream, 948 SilcCipher *send_key, SilcCipher *receive_key, 949 SilcHmac *send_hmac, SilcHmac *receive_hmac); 950 951 /****f* silccore/SilcPacketAPI/silc_packet_set_ids 952 * 953 * SYNOPSIS 954 * 955 * SilcBool silc_packet_set_ids(SilcPacketStream stream, 956 * SilcIdType src_id_type, const void *src_id 957 * SilcIdType dst_id_type, const void *dst_id); 958 * 959 * DESCRIPTION 960 * 961 * Set the source ID and destination ID to be used when sending packets to 962 * this packet stream. The IDs to be used for a packet stream can be 963 * overridden when sending packets. However, if the IDs do not ever change 964 * for the packet stream it is recommended they are set using this function. 965 * In this case they can be omitted when sending packets to the stream. 966 * It is also possible to set only source or destination ID. 967 * 968 ***/ 969 SilcBool silc_packet_set_ids(SilcPacketStream stream, 970 SilcIdType src_id_type, const void *src_id, 971 SilcIdType dst_id_type, const void *dst_id); 972 973 /****f* silccore/SilcPacketAPI/silc_packet_get_ids 974 * 975 * SYNOPSIS 976 * 977 * SilcBool silc_packet_get_ids(SilcPacketStream stream, 978 * SilcBool *src_id_set, SilcID *src_id, 979 * SilcBool *dst_id_set, SilcID *dst_id); 980 * 981 * DESCRIPTION 982 * 983 * Returns source and destination IDs from the packet stream. The 984 * `src_id_set' is set to TRUE if the source ID was returned. The 985 * `dst_id_set' is set to TRUE if the destination ID was returned. 986 * 987 ***/ 988 SilcBool silc_packet_get_ids(SilcPacketStream stream, 989 SilcBool *src_id_set, SilcID *src_id, 990 SilcBool *dst_id_set, SilcID *dst_id); 991 992 /****f* silccore/SilcPacketAPI/silc_packet_set_sid 993 * 994 * SYNOPSIS 995 * 996 * SilcBool silc_packet_set_sid(SilcPacketStream stream, SilcUInt8 sid); 997 * 998 * DESCRIPTION 999 * 1000 * Sets new Security ID to the packet stream indicated by `stream'. This 1001 * is called only if the IV Included property was set to the stream 1002 * by calling silc_packet_stream_set_iv_included. This function sets 1003 * new Security ID to the stream which is then included in the ciphertext 1004 * of a packet. The `sid' must be 0 when it is set for the very first 1005 * time and must be increased by one after each rekey. This function must 1006 * be called every time new keys are added to the stream after a rekey. 1007 * 1008 * If this function is called when the IV Included property has not been 1009 * set to the stream the `sid' will be ignored. Returns FALSE if the 1010 * IV Included has not been set, TRUE otherwise. 1011 * 1012 ***/ 1013 SilcBool silc_packet_set_sid(SilcPacketStream stream, SilcUInt8 sid); 1014 1015 /****f* silccore/SilcPacketAPI/silc_packet_send 1016 * 1017 * SYNOPSIS 1018 * 1019 * SilcBool silc_packet_send(SilcPacketStream stream, 1020 * SilcPacketType type, SilcPacketFlags flags, 1021 * const unsigned char *data, 1022 * SilcUInt32 data_len); 1023 * 1024 * DESCRIPTION 1025 * 1026 * Send `data' of length of `data_len' to the packet stream indicated by 1027 * `stream'. If ciphers and HMACs were set using silc_packet_set_keys 1028 * the packet will be encrypted and MAC will be computed for it. If 1029 * silc_packet_set_ids was used to set source and destination ID for the 1030 * packet stream those IDs are used in the packet. If IDs have not been 1031 * set and they need to be provided then silc_packet_send_ext function 1032 * should be used. Otherwise, the packet will not have IDs set at all. 1033 * Returns FALSE if packet could not be sent. 1034 * 1035 ***/ 1036 SilcBool silc_packet_send(SilcPacketStream stream, 1037 SilcPacketType type, SilcPacketFlags flags, 1038 const unsigned char *data, SilcUInt32 data_len); 1039 1040 /****f* silccore/SilcPacketAPI/silc_packet_send_ext 1041 * 1042 * SYNOPSIS 1043 * 1044 * SilcBool 1045 * silc_packet_send_ext(SilcPacketStream stream, 1046 * SilcPacketType type, SilcPacketFlags flags, 1047 * SilcIdType src_id_type, void *srd_id, 1048 * SilcIdType dst_id_type, void *dst_id, 1049 * const unsigned char *data, SilcUInt32 data_len, 1050 * SilcCipher cipher, SilcHmac hmac); 1051 * 1052 * DESCRIPTION 1053 * 1054 * Same as silc_packet_send but with this function different sending 1055 * parameters can be sent as argument. This function can be used to 1056 * set specific IDs, cipher and HMAC to be used in packet sending, 1057 * instead of the ones saved in the `stream'. If any of the extra 1058 * pointers are NULL, default values set to the stream will apply. 1059 * 1060 ***/ 1061 SilcBool silc_packet_send_ext(SilcPacketStream stream, 1062 SilcPacketType type, SilcPacketFlags flags, 1063 SilcIdType src_id_type, void *src_id, 1064 SilcIdType dst_id_type, void *dst_id, 1065 const unsigned char *data, SilcUInt32 data_len, 1066 SilcCipher cipher, SilcHmac hmac); 1067 1068 /****f* silccore/SilcPacketAPI/silc_packet_send_va 1069 * 1070 * SYNOPSIS 1071 * 1072 * SilcBool silc_packet_send_va(SilcPacketStream stream, 1073 * SilcPacketType type, 1074 * SilcPacketFlags flags, ...); 1075 * 1076 * DESCRIPTION 1077 * 1078 * Same as silc_packet_send but takes the data in as variable argument 1079 * formatted buffer (see silcbuffmt.h). The arguments must be ended 1080 * with SILC_STR_END. Returns FALSE if packet could not be sent or 1081 * the buffer could not be formatted. 1082 * 1083 * EXAMPLE 1084 * 1085 * // Send NEW_CLIENT packet 1086 * silc_packet_send_va(stream, SILC_PACKET_NEW_CLIENT, 0, 1087 * SILC_STR_UI_SHORT(username_len), 1088 * SILC_STR_DATA(username, username_len), 1089 * SILC_STR_UI_SHORT(realname_len), 1090 * SILC_STR_DATA(realname, realname_len), 1091 * SILC_STR_END); 1092 * 1093 ***/ 1094 SilcBool silc_packet_send_va(SilcPacketStream stream, 1095 SilcPacketType type, SilcPacketFlags flags, ...); 1096 1097 /****f* silccore/SilcPacketAPI/silc_packet_send_va_ext 1098 * 1099 * SYNOPSIS 1100 * 1101 * SilcBool 1102 * silc_packet_send_va_ext(SilcPacketStream stream, 1103 * SilcPacketType type, SilcPacketFlags flags, 1104 * SilcIdType src_id_type, void *srd_id, 1105 * SilcIdType dst_id_type, void *dst_id, 1106 * SilcCipher cipher, SilcHmac hmac, ...); 1107 * 1108 * DESCRIPTION 1109 * 1110 * Same as silc_packet_send_va but with this function different sending 1111 * parameters can be sent as argument. This function can be used to 1112 * set specific IDs, cipher and HMAC to be used in packet sending, 1113 * instead of the ones saved in the `stream'. If any of the extra 1114 * pointers are NULL, default values set to the stream will apply. 1115 * 1116 ***/ 1117 SilcBool silc_packet_send_va_ext(SilcPacketStream stream, 1118 SilcPacketType type, SilcPacketFlags flags, 1119 SilcIdType src_id_type, void *src_id, 1120 SilcIdType dst_id_type, void *dst_id, 1121 SilcCipher cipher, SilcHmac hmac, ...); 1122 1123 /****f* silccore/SilcPacketAPI/silc_packet_wait_init 1124 * 1125 * SYNOPSIS 1126 * 1127 * void *silc_packet_wait_init(SilcPacketStream stream, 1128 * const SilcID *source_id, ...); 1129 * 1130 * DESCRIPTION 1131 * 1132 * Initializes a packet waiter for the packet stream `stream' and 1133 * for the variable argument list of packet types. The function 1134 * silc_packet_wait can be used to block the thread until a packet 1135 * has been received. 1136 * 1137 * This function is used to initialize the waiting and to give the list 1138 * of packet types that caller wish to receive. The variable argument 1139 * list must end with -1. To receive all packets use SILC_PACKET_ANY. 1140 * If the `source_id' is non-NULL then only packets of the specified 1141 * type from the specified `source_id' are received. If it is NULL 1142 * then the packet source is ignored. 1143 * 1144 * Returns a context that must be given to the silc_packet_wait function 1145 * as argument. Returns NULL on error. To uninitialize the waiting 1146 * call silc_packet_wait_uninit. 1147 * 1148 * NOTES 1149 * 1150 * Note that packets may be available immediately after calling this 1151 * function and they will be buffered, until silc_packet_wait is called. 1152 * 1153 * EXAMPLE 1154 * 1155 * void *waiter; 1156 * 1157 * // Will wait for private message packets 1158 * waiter = silc_packet_wait_init(stream, NULL, 1159 * SILC_PACKET_PRIVATE_MESSAGE, -1); 1160 * 1161 ***/ 1162 void *silc_packet_wait_init(SilcPacketStream stream, 1163 const SilcID *source_id, ...); 1164 1165 /****f* silccore/SilcPacketAPI/silc_packet_wait_uninit 1166 * 1167 * SYNOPSIS 1168 * 1169 * void silc_packet_wait_uninit(void *waiter, SilcPacketStream stream); 1170 * 1171 * DESCRIPTION 1172 * 1173 * Uninitializes the waiting context. This may be called also from 1174 * another thread while other thread is waiting for packets. This will 1175 * inform the waiting thread to stop waiting. 1176 * 1177 ***/ 1178 void silc_packet_wait_uninit(void *waiter, SilcPacketStream stream); 1179 1180 /****f* silccore/SilcPacketAPI/silc_packet_wait 1181 * 1182 * SYNOPSIS 1183 * 1184 * int silc_packet_wait(void *waiter, int timeout, 1185 * SilcPacket *return_packet) 1186 * 1187 * DESCRIPTION 1188 * 1189 * A special function that can be used to wait for a packet to arrive. 1190 * This function will block the calling process or thread until either 1191 * a packet is received into the `return_packet' pointer or the specified 1192 * timeout value `timeout', which is in milliseconds, will expire. If 1193 * the timeout is 0, no timeout exist. Before calling this function the 1194 * silc_packet_wait_init must be called. The caller is responsible for 1195 * freeing the returned packet with silc_packet_free. 1196 * 1197 * This function can be used for example from a thread that wants to 1198 * block until SILC packet has been received. 1199 * 1200 * Returns 1 when packet was received, 0 if timeout occurred and -1 if 1201 * error occurred. 1202 * 1203 * EXAMPLE 1204 * 1205 * static int foo_read_data(FooContext c) 1206 * { 1207 * SilcPacket packet; 1208 * void *waiter; 1209 * ... 1210 * 1211 * // Will wait for private message packets 1212 * if (c->initialized == FALSE) { 1213 * waiter = silc_packet_wait_init(stream, 1214 * SILC_PACKET_PRIVATE_MESSAGE, -1); 1215 * c->initialized = TRUE; 1216 * } 1217 * 1218 * ... 1219 * // Wait here until private message packet is received 1220 * if ((silc_packet_wait(waiter, 0, &packet)) < 0) 1221 * return -1; 1222 * 1223 * ... process packet ... 1224 * 1225 * return 1; 1226 * } 1227 * 1228 ***/ 1229 int silc_packet_wait(void *waiter, int timeout, SilcPacket *return_packet); 1230 1231 /****f* silccore/SilcPacketAPI/silc_packet_free 1232 * 1233 * SYNOPSIS 1234 * 1235 * void silc_packet_free(SilcPacket packet); 1236 * 1237 * DESCRIPTION 1238 * 1239 * This function is used to free the SilcPacket pointer that application 1240 * receives in the SilcPacketReceive callback. Application must free 1241 * the packet if it takes it in to processing. 1242 * 1243 ***/ 1244 void silc_packet_free(SilcPacket packet); 1245 1246 #endif /* SILCPACKET_H */ 1247