Fix reference count bug leading to memory corruption on duplicate deletions.
[silc.git] / lib / silcclient / client.h
index d60b740a9ab8586440dd9f04002185ab4d7b9f97..ebe41fe903f752ee261e14cd18edd51e7042adad 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2006 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
@@ -31,7 +31,6 @@ typedef struct SilcClientEntryStruct *SilcClientEntry;
 typedef struct SilcChannelEntryStruct *SilcChannelEntry;
 typedef struct SilcServerEntryStruct *SilcServerEntry;
 
-typedef struct SilcClientAwayStruct SilcClientAway;
 typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
 typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession;
 typedef struct SilcClientCommandReplyContextStruct
@@ -39,12 +38,13 @@ typedef struct SilcClientCommandReplyContextStruct
 typedef struct SilcChannelUserStruct *SilcChannelUser;
 typedef struct SilcClientInternalStruct *SilcClientInternal;
 typedef struct SilcClientConnectionInternalStruct
-                                          *SilcClientConnectionInternal;
+     *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 */
@@ -54,17 +54,21 @@ typedef struct SilcClientEntryInternalStruct {
   SilcClientKeyAgreement ke;   /* Current key agreement context or NULL */
 
   /* Flags */
-  unsigned int valid       : 1;        /* FALSE if this entry is not valid */
-  unsigned int resolving   : 1; /* TRUE when entry is being resolved */
+  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 private message key indicator
-                                  has been received (responder). */
+  unsigned int prv_resp    : 1; /* TRUE if we are responder when using
+                                  private message keys. */
   SilcUInt16 resolve_cmd_ident;        /* Command identifier when resolving */
-  SilcAtomic8 refcnt;          /* Reference counter */
+  SilcAtomic32 refcnt;         /* Reference counter */
+  SilcAtomic32 deleted;     /* Flag indicating whether the client object is
+                                                                          already scheduled for deletion.*/
 } SilcClientEntryInternal;
 
 /* Internal channel entry context */
 typedef struct SilcChannelEntryInternalStruct {
+  SilcRwLock lock;                          /* Read/write lock */
+
   /* SilcChannelEntry status information */
   SilcDList old_channel_keys;
   SilcDList old_hmacs;
@@ -74,7 +78,8 @@ typedef struct SilcChannelEntryInternalStruct {
   SilcChannelPrivateKey curr_key;           /* Current private key */
 
   /* Channel keys */
-  SilcCipher channel_key;                    /* The channel key */
+  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 */
 
@@ -84,13 +89,16 @@ typedef struct SilcChannelEntryInternalStruct {
                                                stuff that relates to the
                                                channel. Not used for the
                                                channel resolving itself. */
-  SilcAtomic8 refcnt;                       /* Reference counter */
+  SilcAtomic32 refcnt;                      /* Reference counter */
+  SilcAtomic32 deleted;     /* Flag indicating whether the channel object is
+                                                                          already scheduled for deletion.*/
 } SilcChannelEntryInternal;
 
 /* Internal server entry context */
 typedef struct SilcServerEntryInternalStruct {
+  SilcRwLock lock;                          /* Read/write lock */
   SilcUInt16 resolve_cmd_ident;                     /* Resolving identifier */
-  SilcAtomic8 refcnt;                       /* Reference counter */
+  SilcAtomic32 refcnt;                      /* Reference counter */
 } SilcServerEntryInternal;
 
 #endif /* CLIENT_H */