Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
- Copyright (C) 1997 - 2000 Pekka Riikonen
+ Copyright (C) 1997 - 2001 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
#ifndef CLIENT_H
#define CLIENT_H
-/* Forward declaration for client */
-typedef struct SilcClientObject *SilcClient;
-
-/* Forward declaration for client connection */
-typedef struct SilcClientConnectionObject *SilcClientConnection;
+/* Forward declarations */
+typedef struct SilcClientStruct *SilcClient;
+typedef struct SilcClientConnectionStruct *SilcClientConnection;
+typedef struct SilcClientPingStruct SilcClientPing;
+typedef struct SilcClientAwayStruct SilcClientAway;
+typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
#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;
+#include "silcapi.h"
/* Connection structure used in client to associate all the important
connection specific data to this structure. */
-struct SilcClientConnectionObject {
+struct SilcClientConnectionStruct {
/*
* Local data
*/
/* 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;
+ uint32 local_id_data_len;
/* Own client entry. */
SilcClientEntry local_entry;
/* 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;
+ uint32 remote_id_data_len;
/*
* Common data
*/
- /* Keys */
+ /* Keys and stuff negotiated in the SKE protocol */
SilcCipher send_key;
SilcCipher receive_key;
SilcHmac hmac;
unsigned char *hmac_key;
- unsigned int hmac_key_len;
+ uint32 hmac_key_len;
+ SilcHash hash;
/* Client ID and Channel ID cache. Messages transmitted in SILC network
are done using different unique ID's. These are the cache for
referencing (sock->user_data). */
SilcSocketConnection sock;
+ /* Pending command queue for this connection */
+ SilcDList pending_commands;
+
+ /* Current command identifier, 0 not used */
+ uint16 cmd_ident;
+
/* Requested pings. */
SilcClientPing *ping;
- unsigned int ping_count;
+ uint32 ping_count;
/* Set away message */
SilcClientAway *away;
};
/* Main client structure. */
-struct SilcClientObject {
+struct SilcClientStruct {
/*
* Public data. All the following pointers must be set by the allocator
* of this structure.
/* Table of connections in client. All the connection data is saved here. */
SilcClientConnection *conns;
- unsigned int conns_count;
+ uint32 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;
+ uint32 sockets_count;
/* Generic cipher and hash objects. These can be used and referenced
by the application as well. */
int __i; \
\
for (__i = 0; __i < (__x)->conns_count; __i++) \
- if ((__x)->conns[__i]->sock->sock == (__fd)) \
+ if ((__x)->conns[__i] && \
+ (__x)->conns[__i]->sock->sock == (__fd)) \
break; \
\
- if (__i >= (__x)->conns_count) \
+ if (__i >= (__x)->conns_count) { \
(__sock) = NULL; \
- (__sock) = (__x)->conns[__i]->sock; \
+ for (__i = 0; __i < (__x)->sockets_count; __i++) \
+ if ((__x)->sockets[__i] && \
+ (__x)->sockets[__i]->sock == (__fd)) \
+ (__sock) = (__x)->sockets[__i]; \
+ } else \
+ (__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);
+/* Prototypes (some of the prototypes are defined in the silcapi.h) */
+
void silc_client_packet_send(SilcClient client,
SilcSocketConnection sock,
SilcPacketType type,
SilcCipher cipher,
SilcHmac hmac,
unsigned char *data,
- unsigned int data_len,
+ uint32 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);
+SilcChannelEntry silc_client_new_channel_id(SilcClient client,
+ SilcSocketConnection sock,
+ char *channel_name,
+ uint32 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);
SilcClientConnection conn,
SilcClientEntry old,
SilcClientEntry new);
+char *silc_client_chmode(uint32 mode, SilcChannelEntry channel);
+char *silc_client_chumode(uint32 mode);
+char *silc_client_chumode_char(uint32 mode);
+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);
#endif