src/modules/dispatcher/dispatch.h
31ccf6a2
 /**
  * dispatcher module
335a62bb
  *
31ccf6a2
  * Copyright (C) 2004-2006 FhG Fokus
  *
27642a08
  * This file is part of Kamailio, a free SIP server.
31ccf6a2
  *
27642a08
  * Kamailio is free software; you can redistribute it and/or modify
31ccf6a2
  * 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
  *
27642a08
  * Kamailio is distributed in the hope that it will be useful,
31ccf6a2
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
335a62bb
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
9e1ff448
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
31ccf6a2
  */
 
aecdbe9b
 /*! \file
  * \ingroup dispatcher
  * \brief Dispatcher :: Dispatch
  */
 
31ccf6a2
 #ifndef _DISPATCH_H_
 #define _DISPATCH_H_
 
a4ba0359
 #include <stdio.h>
cf83221d
 #include "../../core/pvar.h"
3933a64c
 #include "../../core/xavp.h"
cf83221d
 #include "../../core/parser/msg_parser.h"
 #include "../../core/rand/kam_rand.h"
eb38b3df
 #include "../../modules/tm/tm_load.h"
31ccf6a2
 
ee4a9fb2
 
d081ee4e
 /* clang-format off */
aecdbe9b
 #define DS_HASH_USER_ONLY	1  /*!< use only the uri user part for hashing */
 #define DS_FAILOVER_ON		2  /*!< store the other dest in avps */
081b5d4e
 
aecdbe9b
 #define DS_INACTIVE_DST		1  /*!< inactive destination */
cbe2e236
 #define DS_TRYING_DST		2  /*!< temporary trying destination */
241a05bc
 #define DS_DISABLED_DST		4  /*!< admin disabled destination */
cbe2e236
 #define DS_PROBING_DST		8  /*!< checking destination */
9eba5b67
 #define DS_NODNSARES_DST	16 /*!< no DNS A/AAAA resolve for host in uri */
 #define DS_STATES_ALL		31 /*!< all bits for the states of destination */
081b5d4e
 
25bedcd9
 #define ds_skip_dst(flags)	((flags) & (DS_INACTIVE_DST|DS_DISABLED_DST))
 
d6654584
 #define DS_PROBE_NONE		0
 #define DS_PROBE_ALL		1
 #define DS_PROBE_INACTIVE	2
65a442a2
 #define DS_PROBE_ONLYFLAGGED	3
d6654584
 
6016958d
 #define DS_MATCH_ALL		0
 #define DS_MATCH_NOPORT		1
 #define DS_MATCH_NOPROTO	2
2945ba44
 #define DS_MATCH_ACTIVE 	4
11ff4226
 
f6960f87
 #define DS_SETOP_DSTURI		0
 #define DS_SETOP_RURI		1
 #define DS_SETOP_XAVP		2
 
b55b6fa1
 #define DS_USE_CRT			0
 #define DS_USE_NEXT			1
 
11ff4226
 #define DS_XAVP_DST_SKIP_ATTRS	1
8507efe8
 #define DS_XAVP_DST_ADD_SOCKSTR	(1<<1)
80930085
 #define DS_XAVP_DST_ADD_SOCKNAME	(1<<2)
b55b6fa1
 
11ff4226
 #define DS_XAVP_CTX_SKIP_CNT	1
 
9eba5b67
 #define DS_IRMODE_NOIPADDR	1
d081ee4e
 /* clang-format on */
6016958d
 
9d59f5cb
 typedef struct ds_rctx {
 	int flags;
 	int code;
 	str reason;
 } ds_rctx_t;
 
e2cf6343
 extern str ds_db_url;
 extern str ds_table_name;
 extern str ds_set_id_col;
 extern str ds_dest_uri_col;
c7d56382
 extern str ds_dest_flags_col;
9de77c2b
 extern str ds_dest_priority_col;
65160302
 extern str ds_dest_attrs_col;
a4ba0359
 
335a62bb
 extern int ds_flags;
8cdef0e8
 extern int ds_use_default;
 
11ff4226
 extern str ds_xavp_dst;
 extern int ds_xavp_dst_mode;
 extern str ds_xavp_ctx;
 extern int ds_xavp_ctx_mode;
 
 extern str ds_xavp_dst_addr;
 extern str ds_xavp_dst_grp;
 extern str ds_xavp_dst_dstid;
 extern str ds_xavp_dst_attrs;
 extern str ds_xavp_dst_sock;
8507efe8
 extern str ds_xavp_dst_socket;
80930085
 extern str ds_xavp_dst_sockname;
11ff4226
 
 extern str ds_xavp_ctx_cnt;
ee4a9fb2
 
d081ee4e
 extern pv_elem_t *hash_param_model;
095ab21d
 
b14bb7d7
 extern str ds_setid_pvname;
 extern pv_spec_t ds_setid_pv;
09a7a4cd
 extern str ds_attrs_pvname;
 extern pv_spec_t ds_attrs_pv;
b14bb7d7
 
081b5d4e
 /* Structure containing pointers to TM-functions */
441ab3c9
 extern struct tm_binds tmb;
101e9af4
 extern str ds_ping_method;
 extern str ds_ping_from;
d081ee4e
 extern int probing_threshold;  /*!< number of failed requests,
2fe8749a
 								before a destination is taken into probing */
335a62bb
 extern int inactive_threshold; /*!< number of successful requests,
2fe8749a
 								before a destination is taken into active */
d1de0cc5
 extern int ds_probing_mode;
a201a338
 extern str ds_outbound_proxy;
aae77585
 extern str ds_default_socket;
80930085
 extern str ds_default_sockname;
d081ee4e
 extern struct socket_info *ds_default_sockinfo;
081b5d4e
 
4e7e355d
 int ds_init_data(void);
 int ds_init_db(void);
31ccf6a2
 int ds_load_list(char *lfile);
5ddbf042
 int ds_connect_db(void);
 void ds_disconnect_db(void);
 int ds_load_db(void);
96e76014
 int ds_reload_db(void);
5ddbf042
 int ds_destroy_list(void);
3933a64c
 int ds_select_dst_limit(sip_msg_t *msg, int set, int alg, uint32_t limit,
 		int mode);
a4ba0359
 int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode);
b55b6fa1
 int ds_update_dst(struct sip_msg *msg, int upos, int mode);
2e842e9c
 int ds_add_dst(int group, str *address, int flags, str *attrs);
d9a9e5f5
 int ds_remove_dst(int group, str *address);
9d59f5cb
 int ds_update_state(sip_msg_t *msg, int group, str *address, int state,
 		ds_rctx_t *rctx);
241a05bc
 int ds_reinit_state(int group, str *address, int state);
d8cc8626
 int ds_reinit_state_all(int group, int state);
b7b0f258
 int ds_reinit_duid_state(int group, str *vduid, int state);
a4ba0359
 int ds_mark_dst(struct sip_msg *msg, int mode);
 int ds_print_list(FILE *fout);
996f50eb
 int ds_log_sets(void);
bef88a0d
 int ds_list_exist(int set);
 
31ccf6a2
 
9cdc3e70
 int ds_load_unset(struct sip_msg *msg);
 int ds_load_update(struct sip_msg *msg);
 
 int ds_hash_load_init(unsigned int htsize, int expire, int initexpire);
 int ds_hash_load_destroy(void);
 
081b5d4e
 int ds_is_from_list(struct sip_msg *_m, int group);
6016958d
 int ds_is_addr_from_list(sip_msg_t *_m, int group, str *uri, int mode);
 
aecdbe9b
 /*! \brief
081b5d4e
  * Timer for checking inactive destinations
  */
d081ee4e
 void ds_check_timer(unsigned int ticks, void *param);
081b5d4e
 
59c31fe7
 
 /*! \brief
  * Timer for checking active calls load
  */
 void ds_ht_timer(unsigned int ticks, void *param);
 
ec903da3
 /*! \brief
  * Check if the reply-code is valid:
  */
 int ds_ping_check_rplcode(int);
 
d081ee4e
 /* clang-format off */
 typedef struct _ds_attrs {
d997ecfc
 	str body;
 	str duid;
aae77585
 	str socket;
80930085
 	str sockname;
d997ecfc
 	int maxload;
 	int weight;
1d6c1d74
 	int rweight;
1d304002
 	int congestion_control;
3f9c38be
 	str ping_from;
74ef108f
 	str obproxy;
d997ecfc
 } ds_attrs_t;
 
12a25ed7
 typedef struct _ds_latency_stats {
 	struct timeval start;
 	int min;
 	int max;
 	float average;  // weigthed average, estimate of the last few weeks
 	float stdev;    // last standard deviation
 	float estimate; // short term estimate, EWMA exponential weighted moving average
b103fefd
 	double m2;      // sum of squares, used for recursive variance calculation
12a25ed7
 	int32_t count;
 	uint32_t timeout;
 } ds_latency_stats_t;
 
6e50e27d
 void latency_stats_init(ds_latency_stats_t *latency_stats, int latency, int count);
 
d081ee4e
 typedef struct _ds_dest {
9eba5b67
 	str uri;          /*!< address/uri */
 	int flags;        /*!< flags */
 	int priority;     /*!< priority */
 	int dload;        /*!< load */
 	ds_attrs_t attrs; /*!< the atttributes */
 	ds_latency_stats_t latency_stats; /*!< latency statistics */
 	int irmode;       /*!< internal runtime mode (flags) */
 	struct socket_info *sock; /*!< pointer to local socket */
 	struct ip_addr ip_address; 	/*!< IP of the address */
 	unsigned short int port; 	/*!< port of the URI */
 	unsigned short int proto; 	/*!< protocol of the URI */
2e567ce1
 	int message_count;
d997ecfc
 	struct _ds_dest *next;
 } ds_dest_t;
 
d081ee4e
 typedef struct _ds_set {
d997ecfc
 	int id;				/*!< id of dst set */
 	int nr;				/*!< number of items in dst set */
 	int last;			/*!< last used item in dst set (round robin) */
 	int wlast;			/*!< last used item in dst set (by weight) */
877f768d
 	int rwlast;			/*!< last used item in dst set (by relative weight) */
d997ecfc
 	ds_dest_t *dlist;
 	unsigned int wlist[100];
1d6c1d74
 	unsigned int rwlist[100];
996f50eb
 	struct _ds_set *next[2];
98f9cace
 	int longer;
1d304002
 	gen_lock_t lock;
d997ecfc
 } ds_set_t;
3933a64c
 
 typedef struct _ds_select_state {
074d3c67
 	int setid;  /* dispatcher set id (group id) */
 	int alg;    /* algorithm to select destionations */
 	int umode;  /* update mode - push to: r-uri, d-uri, xavp */
 	uint32_t limit; /* limit of destination addresses to be selected */
 	int cnt;    /* output: number of xavps set with destination addresses */
 	int emode;  /* output: update operation was executed or not */
3933a64c
 	sr_xavp_t *lxavp;
 } ds_select_state_t;
 
d9a9e5f5
 struct ds_filter_dest_cb_arg {
 	int setid;
 	ds_dest_t *dest;
 	int *setn;
 };
 
d081ee4e
 /* clang-format on */
 
996f50eb
 #define AVL_LEFT 0
 #define AVL_RIGHT 1
 #define AVL_NEITHER -1
 #define AVL_BALANCED(n) (n->longer < 0)
d997ecfc
 
 ds_set_t *ds_get_list(void);
 int ds_get_list_nr(void);
44c5d1c0
 
 int ds_ping_active_init(void);
 int ds_ping_active_get(void);
 int ds_ping_active_set(int v);
 
d081ee4e
 /* Create if not exist and return ds_set_t by id */
 ds_set_t *ds_avl_insert(ds_set_t **root, int id, int *setn);
 ds_set_t *ds_avl_find(ds_set_t *node, int id);
 void ds_avl_destroy(ds_set_t **node);
996f50eb
 
3933a64c
 int ds_manage_routes(sip_msg_t *msg, ds_select_state_t *rstate);
 
9d59f5cb
 ds_rctx_t* ds_get_rctx(void);
aac6c77c
 unsigned int ds_get_hash(str *x, str *y);
9d59f5cb
 
31ccf6a2
 #endif