/*
 * Copyright (c) 2003-2006 Sendmail, Inc. and its suppliers.
 *      All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 *
 *	$Id: dadbstr.h,v 1.23 2007/05/28 17:15:36 ca Exp $
 */

#ifndef SM_DADBSTR_H
#define SM_DADBSTR_H 1

#include "sm/generic.h"
#include "sm/magic.h"
#include "sm/types.h"
#include "sm/pthread.h"
#include "sm/net.h"
#include "sm/ring.h"
#include "sm/str.h"

#ifndef DADB_CHECK
# define DADB_CHECK	1
#endif

typedef struct dadb_ctx_S	dadb_ctx_T, *dadb_ctx_P;
typedef struct dadb_entry_S	dadb_entry_T, *dadb_entry_P;

/*
**  Delivery Agent (SMTPC) DataBase Context
**  For each SMTP client process one dadb_ctx is created which keeps track
**  of that client.  It keeps track of all possible threads in that process
**  by creating an array of dadb_entries.  The size of that array is the
**  maximum number of threads in the DA.  The number of active entries can
**  be dynamically limited to control the load the DA generates.
**  Each dadb_entry describes a session in the DA.
*/

struct dadb_ctx_S
{
#if DADB_CHECK
	sm_magic_T	 sm_magic;
#endif
	/* locks state, entries_{lim,cur}, entries */
	pthread_mutex_t	 dadb_mutex;

	/*
	**  dadb_state MUST be checked by every function that wants to
	**  access/modify elements of dadb_ctx.
	**  This way state can be used as additional "mutex" for dadb_ctx:
	**  lock(dadb_mutex);
	**  check state: don't do anything if !DADB_IS_OK() (except unlock)
	**  to stop others: set state appropriately
	**  unlock(dadb_mutex);
	*/

	uint		 dadb_state;
	uint		 dadb_entries_max;	/* maximum number of entries */
	uint		 dadb_entries_lim;	/* current max (dynamic) */
	uint		 dadb_entries_cur;	/* current number of entries */
	uint		 dadb_entries_idle;	/* idle entries */

	dadb_entry_P	*dadb_entries;	/* array of entries for DA status */
	/* this array is from 0 to dadb_entries_max-1 */

#if DADB_STATS
	/* maximum number of entries ever used (statistics only) */
	uint		 dadb_entries_max_used;
#endif
};

struct dadb_entry_S
{
#if DADB_CHECK
	sm_magic_T	 sm_magic;
#endif
#if DADBE_MUTEX
	pthread_mutex_t	 dadbe_mutex;	/* really needed??? */
#endif
	uint		 dadbe_flags;

	/*
	**  DA session id: primary key in bht(? not yet!)
	**  only used to tell DA the session id
	*/

	sessta_id_T	 dadbe_da_se_id;

	/* DA transaction id: secondary key in bht */
	sessta_id_T	 dadbe_da_ta_id;
	sessta_id_T	 dadbe_ss_ta_id;	/* copy of SMTPS TA id */

	/* this doesn't belong here... -> OCC (open connection cache) */
	ipv4_T		 dadbe_srv_ipv4;		/* XXX HACK! */

	/*
	**  Pointer to one recipient for the transaction.
	**  Outgoing from this rcpt all others can be found via aqr_da_link
	**  in the aq_rcpt structure.
	*/

	aq_rcpt_P	 dadbe_rcpt;

	time_T		 dadbe_lastuse;	/* DA last used */

#if MTA_USE_TLS
	sm_ret_T	 dadbe_se_maprescnf;	/* map lookup result for session conf */
	sm_str_P	 dadbe_se_conf;	/* extra session configuration data */

	sm_str_P	 dadbe_lhs;
	sm_str_P	 dadbe_tag;
#endif

#if DADB_STATS
	/* statistics; used to implement limits */
	uint		 dadbe_ntas;	/* number of transactions */
	uint		 dadbe_nrcpts;	/* number of recipients */
	time_T		 dadbe_opened;	/* session opened */
#endif /* DA_DB_STATS */
};

#if DADB_CHECK
# define SM_IS_DADB(dadb)	SM_REQUIRE_ISA((dadb), SM_DADB_MAGIC)
# define SM_IS_DADBE(dadbe)	SM_REQUIRE_ISA((dadbe), SM_DADBE_MAGIC)
#else
# define SM_IS_DADB(dadb)	SM_REQUIRE((dadb) != NULL)
# define SM_IS_DADBE(dadbe)	SM_REQUIRE((dadbe) != NULL)
#endif

#endif /* SM_DADBSTR_H */


syntax highlighted by Code2HTML, v. 0.9.1