X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient_internal.h;h=a297182024c827335a6caf89aa4e7ac4de015e22;hp=05b1ff36562571e9ff0d4b9f43a594c60b4b4f23;hb=805fddcf6431e784f9f77114782a90c9d12f9cbe;hpb=c257b555225193e54d85daf541d29578b3c93882 diff --git a/lib/silcclient/client_internal.h b/lib/silcclient/client_internal.h index 05b1ff36..a2971820 100644 --- a/lib/silcclient/client_internal.h +++ b/lib/silcclient/client_internal.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2004 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 @@ -20,285 +20,175 @@ #ifndef CLIENT_INTERNAL_H #define CLIENT_INTERNAL_H -/* Context to hold the connection authentication request callbacks that - will be called when the server has replied back to our request about - current authentication method in the session. */ +#include "command.h" +#include "command_reply.h" +#include "client_connect.h" +#include "client_register.h" +#include "client_entry.h" +#include "client_prvmsg.h" +#include "client_channel.h" +#include "client_notify.h" +#include "client_keyagr.h" +#include "client_ftp.h" +#include "client_listener.h" + +/****************************** Definitions *********************************/ + +/* Packet retry counter and timer defines, for exponential backoff algorithm. + Meaningful with UDP transport when packets may get lost. */ +#define SILC_CLIENT_RETRY_COUNT 4 /* Max packet retry count */ +#define SILC_CLIENT_RETRY_MUL 2 /* Retry timer interval growth */ +#define SILC_CLIENT_RETRY_RAND 2 /* Randomizer, timeout += rnd % 2 */ +#define SILC_CLIENT_RETRY_MIN 1 /* Min retry timeout, seconds */ +#define SLIC_CLIENT_RETRY_MAX 16 /* Max retry timeout, seconds */ + +/********************************** Types ***********************************/ + +/* Public key verification context */ typedef struct { - SilcConnectionAuthRequest callback; - void *context; - SilcTask timeout; -} *SilcClientConnAuthRequest; - -/* Generic rekey context for connections */ -typedef struct { - /* Current sending encryption key, provided for re-key. The `pfs' - is TRUE if the Perfect Forward Secrecy is performed in re-key. */ - unsigned char *send_enc_key; - SilcUInt32 enc_key_len; - int ske_group; - bool pfs; - SilcUInt32 timeout; - void *context; -} *SilcClientRekey; - -/* Internal context for connection process. This is needed as we - doing asynchronous connecting. */ -typedef struct { - SilcClient client; - SilcClientConnection conn; - SilcTask task; - int sock; - char *host; - int port; - int tries; - void *context; -} SilcClientInternalConnectContext; - -/* 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. */ -struct SilcClientPingStruct { - time_t start_time; - void *dest_id; - char *dest_name; -}; - -/* 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. */ -struct SilcClientAwayStruct { - char *away; - struct SilcClientAwayStruct *next; -}; + SilcSKE ske; + SilcSKEVerifyCbCompletion completion; + void *completion_context; +} *SilcVerifyKeyContext; + +/* Command and command reply context used to hold registered commands + in the SILC client. */ +typedef struct SilcClientCommandStruct { + struct SilcClientCommandStruct *next; + SilcCommand cmd; /* Command type */ + SilcFSMStateCallback command; /* Command function */ + SilcFSMStateCallback reply; /* Command reply callback */ + char *name; /* Name of the command (optional) */ + SilcUInt8 max_args; /* Maximum arguments (optional) */ +} *SilcClientCommand; + +/* Command reply callback structure */ +typedef struct SilcClientCommandReplyCallbackStruct { + struct SilcClientCommandReplyCallbackStruct *next; + SilcClientCommandReply reply; /* Command reply callback */ + void *context; /* Command reply context */ + unsigned int do_not_call : 1; /* Set to not call the callback */ +} *SilcClientCommandReplyCallback; + +/* Command context given as argument to command state functions. This same + context is used when calling, sending and procesing command and command + reply. */ +typedef struct SilcClientCommandContextStruct { + struct SilcClientCommandContextStruct *next; + SilcClientConnection conn; /* Connection */ + SilcFSMThreadStruct thread; /* FSM thread for command call */ + + SilcCommand cmd; /* Command */ + SilcUInt16 cmd_ident; /* Command identifier */ + SilcUInt32 argc; /* Number of arguments */ + unsigned char **argv; /* Arguments, may be NULL */ + SilcUInt32 *argv_lens; /* Argument lengths, may be NULL */ + SilcUInt32 *argv_types; /* Argument types, may be NULL */ + + SilcList reply_callbacks; /* Command reply callbacks */ + SilcStatus status; /* Current command reply status */ + SilcStatus error; /* Current command reply error */ + + void *context; /* Context for free use */ + unsigned int called : 1; /* Set when called by application */ + unsigned int verbose : 1; /* Verbose with 'say' client operation */ + unsigned int resolved : 1; /* Set when resolving something */ +} *SilcClientCommandContext; /* Internal context for the client->internal pointer in the SilcClient. */ struct SilcClientInternalStruct { - /* All client operations that are implemented by the application. */ - SilcClientOperations *ops; - - /* Client Parameters */ - SilcClientParams *params; - - /* Table of connections in client. All the connection data is saved here. */ - SilcClientConnection *conns; - SilcUInt32 conns_count; - - /* Table of listenning sockets in client. Client can have listeners - (like key agreement protocol server) and those sockets are saved here. - This table is checked always if the connection object cannot be found - from the `conns' table. */ - SilcSocketConnection *sockets; - SilcUInt32 sockets_count; - - /* Registered commands */ - SilcList commands; - - /* Generic cipher and hash objects. */ - SilcCipher none_cipher; - SilcHmac md5hmac; - SilcHmac sha1hmac; - - /* Client version. Used to compare to remote host's version strings. */ - char *silc_client_version; + SilcFSMStruct fsm; /* Client's FSM */ + SilcFSMEventStruct wait_event; /* Event signaller */ + SilcClientOperations *ops; /* Client operations */ + SilcClientParams *params; /* Client parameters */ + SilcPacketEngine packet_engine; /* Packet engine */ + SilcMutex lock; /* Client lock */ + SilcList commands; /* Registered commands */ + SilcDList ftp_sessions; /* FTP sessions */ + char *silc_client_version; /* Version set by application */ + SilcClientRunning running; /* Running/Stopped callback */ + void *running_context; /* Context for runnign callback */ + SilcAtomic32 conns; /* Number of connections in client */ + SilcUInt16 next_session_id; /* Next FTP session ID */ + + /* Events */ + unsigned int stop : 1; /* Stop client */ + unsigned int run_callback : 1; /* Call running/stopped callback */ + unsigned int connection_closed : 1; /* A connection closed */ }; /* Internal context for conn->internal in SilcClientConnection. */ struct SilcClientConnectionInternalStruct { - /* Keys and stuff negotiated in the SKE protocol */ - SilcCipher send_key; - SilcCipher receive_key; - SilcHmac hmac_send; - SilcHmac hmac_receive; - SilcHash hash; - SilcUInt32 psn_send; - SilcUInt32 psn_receive; - - /* 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; - - /* Pending command queue for this connection */ - SilcDList pending_commands; - - /* Requested pings. */ - SilcClientPing *ping; - SilcUInt32 ping_count; - - /* Set away message */ - SilcClientAway *away; - - /* Re-key context */ - SilcClientRekey rekey; - - /* Authentication request context. */ - SilcClientConnAuthRequest connauth; - - /* File transmission sessions */ - SilcDList ftp_sessions; - SilcUInt32 next_session_id; - SilcClientFtpSession active_session; - - /* Requested Attributes */ - SilcHashTable attrs; - - /* Connection parameters */ - SilcClientConnectionParams params; + SilcClientConnectionParams params; /* Connection parameters */ + SilcFSMStruct fsm; /* Connection FSM */ + SilcFSMThreadStruct event_thread; /* FSM thread for events */ + SilcFSMEventStruct wait_event; /* Event signaller */ + SilcSchedule schedule; /* Connection's scheduler */ + SilcMutex lock; /* Connection lock */ + SilcSKE ske; /* Key exchange protocol */ + SilcSKERekeyMaterial rekey; /* Rekey material */ + SilcList thread_pool; /* Packet thread pool */ + SilcList pending_commands; /* Pending commands list */ + SilcHash hash; /* Negotiated hash function */ + SilcHash sha1hash; /* SHA-1 default hash context */ + SilcBuffer local_idp; /* Local ID Payload */ + SilcBuffer remote_idp; /* Remote ID Payload */ + SilcAsyncOperation op; /* Protocols async operation */ + SilcAsyncOperation cop; /* Async operation for application */ + SilcHashTable attrs; /* Configured user attributes */ + SilcStream user_stream; /* Low level stream in connecting */ + char *disconnect_message; /* Disconnection message */ + char *away_message; /* Away message */ + + SilcIDCache client_cache; /* Client entry cache */ + SilcIDCache channel_cache; /* Channel entry cache */ + SilcIDCache server_cache; /* Server entry cache */ + + SilcUInt32 remote_version; /* Remote SILC protocol version */ + SilcAtomic16 cmd_ident; /* Current command identifier */ + SilcUInt8 retry_count; /* Packet retry counter */ + SilcUInt8 retry_timer; /* Packet retry timer */ + SilcClientConnectionStatus status; /* Connection callback status */ + SilcStatus error; /* Connection callback error */ + + /* Events */ + unsigned int connect : 1; /* Connect remote host */ + unsigned int disconnected : 1; /* Disconnect remote connection */ + unsigned int key_exchange : 1; /* Start key exchange */ + unsigned int rekeying : 1; /* Start rekey */ + + /* Flags */ + unsigned int verbose : 1; /* Notify application */ + unsigned int registering : 1; /* Set when registering to network */ + unsigned int rekey_responder : 1; /* Set when rekeying as responder */ + unsigned int auth_request : 1; /* Set when requesting auth method */ }; -/* Session resuming callback */ -typedef void (*SilcClientResumeSessionCallback)(SilcClient client, - SilcClientConnection conn, - bool success, - void *context); - -/* Rekey must be performed at the lastest when this many packets is sent */ -#define SILC_CLIENT_REKEY_THRESHOLD 0xfffffe00 - -/* 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 { \ - silc_schedule_task_add(client->schedule, (fd), \ - silc_client_packet_process, \ - context, 0, 0, \ - SILC_TASK_GENERIC, \ - SILC_TASK_PRI_NORMAL); \ -} while(0) - -#define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd) \ -do { \ - silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE); \ -} while(0) - -#define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd) \ -do { \ - silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | \ - SILC_TASK_WRITE), FALSE); \ -} 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)->internal->conns_count; __i++) \ - if ((__x)->internal->conns[__i] && \ - (__x)->internal->conns[__i]->sock && \ - (__x)->internal->conns[__i]->sock->sock == (__fd)) \ - break; \ - \ - if (__i >= (__x)->internal->conns_count) { \ - (__sock) = NULL; \ - for (__i = 0; __i < (__x)->internal->sockets_count; __i++) \ - if ((__x)->internal->sockets[__i] && \ - (__x)->internal->sockets[__i]->sock == (__fd)) \ - (__sock) = (__x)->internal->sockets[__i]; \ - } else \ - (__sock) = (__x)->internal->conns[__i]->sock; \ -} while(0) - -/* Check whether rekey protocol is active */ -#define SILC_CLIENT_IS_REKEY(sock) \ - (sock->protocol && sock->protocol->protocol && \ - sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) - -/* Prototypes */ - -SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process); -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, - SilcUInt32 data_len, - bool force_send); -int silc_client_packet_send_real(SilcClient client, - SilcSocketConnection sock, - bool force_send); -void silc_client_ftp_free_sessions(SilcClient client, - SilcClientConnection conn); -void silc_client_ftp_session_free(SilcClientFtpSession session); -void silc_client_ftp_session_free_client(SilcClientConnection conn, - SilcClientEntry client_entry); -void silc_client_close_connection_real(SilcClient client, - SilcSocketConnection sock, - SilcClientConnection conn); -void silc_client_disconnected_by_server(SilcClient client, - SilcSocketConnection sock, - SilcBuffer packet); -void silc_client_error_by_server(SilcClient client, - SilcSocketConnection sock, - SilcBuffer message); -void silc_client_receive_new_id(SilcClient client, - SilcSocketConnection sock, - SilcIDPayload idp); -void silc_client_save_channel_key(SilcClient client, - 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_remove_from_channels(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry); -void silc_client_replace_from_channels(SilcClient client, - SilcClientConnection conn, - SilcClientEntry old, - SilcClientEntry newclient); -void silc_client_process_failure(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_key_agreement(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_notify_by_server(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_private_message(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_private_message_key(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_connection_auth_request(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -void silc_client_ftp(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet); -SilcBuffer silc_client_get_detach_data(SilcClient client, - SilcClientConnection conn); -bool silc_client_process_detach_data(SilcClient client, - SilcClientConnection conn, - unsigned char **old_id, - SilcUInt16 *old_id_len); -void silc_client_resume_session(SilcClient client, - SilcClientConnection conn, - SilcClientResumeSessionCallback callback, - void *context); -SilcBuffer silc_client_attributes_process(SilcClient client, - SilcSocketConnection sock, - SilcDList attrs); -void silc_client_packet_queue_purge(SilcClient client, - SilcSocketConnection sock); -SILC_TASK_CALLBACK_GLOBAL(silc_client_rekey_callback); -void -silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd, - SilcStatus status, - bool notify); - -#endif +SILC_FSM_STATE(silc_client_connection_st_run); +SILC_FSM_STATE(silc_client_connection_st_packet); +SILC_FSM_STATE(silc_client_connection_st_close); +SILC_FSM_STATE(silc_client_error); +SILC_FSM_STATE(silc_client_disconnect); +SILC_FSM_STATE(silc_client_st_stop); + +void silc_client_del_connection(SilcClient client, SilcClientConnection conn); +void silc_client_fsm_destructor(SilcFSM fsm, void *fsm_context, + void *destructor_context); +void silc_client_command_free(SilcClientCommandContext cmd); +SilcClientConnection +silc_client_add_connection(SilcClient client, + SilcConnectionType conn_type, + SilcBool connect, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, + char *remote_host, int port, + SilcClientConnectCallback callback, + void *context); +void silc_client_attributes_process(SilcClient client, + SilcClientConnection conn, + SilcDList attrs, + SilcPKCSSignCb sign_cb, + void *context); + +#endif /* CLIENT_INTERNAL_H */