X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient.h;h=d66808dcef168e06473e7168104b18f97430ce43;hp=0cf57a4964d0ae46e8a4f9d2fcdd3952c43b76eb;hb=e9374395ec9747bddd3ea0bfd3e5a17717e97b31;hpb=cf12445d208b8e7a43de5353b4267451340eb23d diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index 0cf57a49..d66808dc 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -2,15 +2,14 @@ client.h - Author: Pekka Riikonen + Author: Pekka Riikonen - Copyright (C) 1997 - 2000 Pekka Riikonen + Copyright (C) 1997 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - + the Free Software Foundation; version 2 of the License. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -21,284 +20,87 @@ #ifndef CLIENT_H #define CLIENT_H -/* Forward declaration for client */ -typedef struct SilcClientObject *SilcClient; - -/* Forward declaration for client connection */ -typedef struct SilcClientConnectionObject *SilcClientConnection; - -#include "idlist.h" -#include "command.h" -#include "ops.h" - -/* Structure to hold ping time information. Every PING command will - add entry of this structure and is removed after reply to the ping - as been received. */ -typedef struct SilcClientPingStruct { - time_t start_time; - void *dest_id; - char *dest_name; -} SilcClientPing; - -/* Structure to hold away messages set by user. This is mainly created - for future extensions where away messages could be set according filters - such as nickname and hostname. For now only one away message can - be set in one connection. */ -typedef struct SilcClientAwayStruct { - char *away; - struct SilcClientAwayStruct *next; -} SilcClientAway; - -/* Connection structure used in client to associate all the important - connection specific data to this structure. */ -struct SilcClientConnectionObject { - /* - * Local data - */ - char *nickname; - - /* Local client ID for this connection */ - SilcClientID *local_id; - - /* Decoded local ID so that the above defined ID would not have - to be decoded for every packet. */ - unsigned char *local_id_data; - unsigned int local_id_data_len; - - /* Own client entry. */ - SilcClientEntry local_entry; - - /* - * Remote data - */ - char *remote_host; - int remote_port; - int remote_type; - char *remote_info; - - /* Remote server ID for this connection */ - SilcServerID *remote_id; - - /* Decoded remote ID so that the above defined ID would not have - to be decoded for every packet. */ - unsigned char *remote_id_data; - unsigned int remote_id_data_len; - - /* - * Common data - */ - /* Keys */ - SilcCipher send_key; - SilcCipher receive_key; - SilcHmac hmac; - unsigned char *hmac_key; - unsigned int hmac_key_len; - - /* Client ID and Channel ID cache. Messages transmitted in SILC network - are done using different unique ID's. These are the cache for - thoses ID's used in the communication. */ - SilcIDCache client_cache; - SilcIDCache channel_cache; - SilcIDCache server_cache; - - /* Current channel on window. All channels are saved (allocated) into - the cache entries. */ - SilcChannelEntry current_channel; - - /* Socket connection object for this connection (window). This - object will have a back-pointer to this window object for fast - referencing (sock->user_data). */ - SilcSocketConnection sock; - - /* Pending command queue for this connection */ - SilcDList pending_commands; - - /* Current command identifier, 0 not used */ - unsigned short cmd_ident; - - /* Requested pings. */ - SilcClientPing *ping; - unsigned int ping_count; - - /* Set away message */ - SilcClientAway *away; - - /* Pointer back to the SilcClient. This object is passed to the application - and the actual client object is accesible through this pointer. */ - SilcClient client; - - /* User data context. Library does not touch this. */ - void *context; -}; - -/* Main client structure. */ -struct SilcClientObject { - /* - * Public data. All the following pointers must be set by the allocator - * of this structure. - */ - - /* Users's username, hostname and realname. */ - char *username; - char *hostname; - char *realname; - - /* Private and public key of the user. */ - SilcPKCS pkcs; - SilcPublicKey public_key; - SilcPrivateKey private_key; - - /* Application specific user data pointer. Client library does not - touch this. */ - void *application; - - /* - * Private data. Following pointers are used internally by the client - * library and should be considered read-only fields. - */ - - /* All client operations that are implemented in the application. */ - SilcClientOperations *ops; - - /* SILC client task queues */ - SilcTaskQueue io_queue; - SilcTaskQueue timeout_queue; - SilcTaskQueue generic_queue; - - /* Table of connections in client. All the connection data is saved here. */ - SilcClientConnection *conns; - unsigned int conns_count; - - /* Generic cipher and hash objects. These can be used and referenced - by the application as well. */ - SilcCipher none_cipher; - SilcHash md5hash; - SilcHash sha1hash; - SilcHmac md5hmac; - SilcHmac sha1hmac; - - /* Random Number Generator. Application should use this as its primary - random number generator. */ - SilcRng rng; -}; - -/* Macros */ - -/* Registers generic task for file descriptor for reading from network and - writing to network. As being generic task the actual task is allocated - only once and after that the same task applies to all registered fd's. */ -#define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd) \ -do { \ - SilcTask tmptask = silc_task_register(client->generic_queue, (fd), \ - silc_client_packet_process, \ - context, 0, 0, \ - SILC_TASK_GENERIC, \ - SILC_TASK_PRI_NORMAL); \ - silc_task_set_iotype(tmptask, SILC_TASK_WRITE); \ -} while(0) - -#define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd) \ -do { \ - silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ)); \ -} while(0) \ - -#define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(fd) \ -do { \ - silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) | \ - (1L << SILC_TASK_WRITE))); \ -} while(0) - -/* Finds socket connection object by file descriptor */ -#define SILC_CLIENT_GET_SOCK(__x, __fd, __sock) \ -do { \ - int __i; \ - \ - for (__i = 0; __i < (__x)->conns_count; __i++) \ - if ((__x)->conns[__i]->sock->sock == (__fd)) \ - break; \ - \ - if (__i >= (__x)->conns_count) \ - (__sock) = NULL; \ - (__sock) = (__x)->conns[__i]->sock; \ -} while(0) - -/* Prototypes */ - -SilcClient silc_client_alloc(SilcClientOperations *ops, void *application); -void silc_client_free(SilcClient client); -int silc_client_init(SilcClient client); -void silc_client_stop(SilcClient client); -void silc_client_run(SilcClient client); -SilcClientConnection silc_client_add_connection(SilcClient client, - char *hostname, - int port, - void *context); -int silc_client_connect_to_server(SilcClient client, int port, - char *host, void *context); -int silc_client_start_key_exchange(SilcClient client, - SilcClientConnection conn, - int fd); -void silc_client_packet_send(SilcClient client, - SilcSocketConnection sock, - SilcPacketType type, - void *dst_id, - SilcIdType dst_id_type, - SilcCipher cipher, - SilcHmac hmac, - unsigned char *data, - unsigned int data_len, - int force_send); -void silc_client_packet_send_to_channel(SilcClient client, - SilcSocketConnection sock, - SilcChannelEntry channel, - unsigned char *data, - unsigned int data_len, - int force_send); -void silc_client_packet_send_private_message(SilcClient client, - SilcSocketConnection sock, - SilcClientEntry client_entry, - unsigned char *data, - unsigned int data_len, - int force_send); -void silc_client_close_connection(SilcClient client, - SilcSocketConnection sock); -void silc_client_disconnected_by_server(SilcClient client, - SilcSocketConnection sock, - SilcBuffer message); -void silc_client_error_by_server(SilcClient client, - SilcSocketConnection sock, - SilcBuffer message); -void silc_client_notify_by_server(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_receive_new_id(SilcClient client, - SilcSocketConnection sock, - SilcIDPayload idp); -void silc_client_new_channel_id(SilcClient client, - SilcSocketConnection sock, - char *channel_name, - unsigned int mode, SilcIDPayload idp); -void silc_client_save_channel_key(SilcClientConnection conn, - SilcBuffer key_payload, - SilcChannelEntry channel); -void silc_client_receive_channel_key(SilcClient client, - SilcSocketConnection sock, - SilcBuffer packet); -void silc_client_channel_message(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_private_message(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_remove_from_channels(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry); -void silc_client_replace_from_channels(SilcClient client, - SilcClientConnection conn, - SilcClientEntry old, - SilcClientEntry new); -char *silc_client_chmode(unsigned int mode); -char *silc_client_chumode(unsigned int mode); -char *silc_client_chumode_char(unsigned int mode); - +#ifndef SILCCLIENT_H +#error "Do not include this header directly" #endif + +/* Forward declarations */ +typedef struct SilcClientStruct *SilcClient; +typedef struct SilcClientConnectionStruct *SilcClientConnection; +typedef struct SilcClientEntryStruct *SilcClientEntry; +typedef struct SilcChannelEntryStruct *SilcChannelEntry; +typedef struct SilcServerEntryStruct *SilcServerEntry; + +typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement; +typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession; +typedef struct SilcClientCommandReplyContextStruct + *SilcClientCommandReplyContext; +typedef struct SilcChannelUserStruct *SilcChannelUser; +typedef struct SilcClientInternalStruct *SilcClientInternal; +typedef struct SilcClientConnectionInternalStruct + *SilcClientConnectionInternal; +typedef struct SilcChannelPrivateKeyStruct *SilcChannelPrivateKey; + +/* Internal client entry context */ +typedef struct SilcClientEntryInternalStruct { + void *prv_waiter; /* Private message packet waiter */ + SilcRwLock lock; /* Read/write lock */ + SilcCipher send_key; /* Private message key for sending */ + SilcCipher receive_key; /* Private message key for receiving */ + SilcHmac hmac_send; /* Private mesage key HMAC for sending */ + SilcHmac hmac_receive; /* Private mesage key HMAC for receiving */ + unsigned char *key; /* Valid if application provided the key */ + SilcUInt32 key_len; /* Key data length */ + SilcClientKeyAgreement ke; /* Current key agreement context or NULL */ + + SilcAtomic32 refcnt; /* Reference counter */ + SilcAtomic32 deleted; /* Flag indicating whether the client object is + already scheduled for deletion */ + SilcUInt16 resolve_cmd_ident; /* Command identifier when resolving */ + + /* Flags */ + unsigned int valid : 1; /* FALSE if this entry is not valid. Entry + without nickname is not valid. */ + unsigned int generated : 1; /* TRUE if library generated `key' */ + unsigned int prv_resp : 1; /* TRUE if we are responder when using + private message keys. */ +} SilcClientEntryInternal; + +/* Internal channel entry context */ +typedef struct SilcChannelEntryInternalStruct { + SilcRwLock lock; /* Read/write lock */ + + /* SilcChannelEntry status information */ + SilcDList old_channel_keys; + SilcDList old_hmacs; + + /* Channel private keys */ + SilcDList private_keys; /* List of private keys or NULL */ + SilcChannelPrivateKey curr_key; /* Current private key */ + + /* Channel keys */ + SilcCipher send_key; /* The channel key */ + SilcCipher receive_key; /* The channel key */ + SilcHmac hmac; /* Current HMAC */ + unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; /* Current IV */ + + SilcAtomic32 refcnt; /* Reference counter */ + SilcAtomic32 deleted; /* Flag indicating whether the + channel object is already + scheduled for deletion */ + SilcUInt16 resolve_cmd_ident; /* Channel information resolving + identifier. This is used when + resolving users, and other + stuff that relates to the + channel. Not used for the + channel resolving itself. */ +} SilcChannelEntryInternal; + +/* Internal server entry context */ +typedef struct SilcServerEntryInternalStruct { + SilcRwLock lock; /* Read/write lock */ + SilcUInt16 resolve_cmd_ident; /* Resolving identifier */ + SilcAtomic32 refcnt; /* Reference counter */ +} SilcServerEntryInternal; + +#endif /* CLIENT_H */