#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "sx/sx.h"
#include "sx/sasl.h"
#include "sx/ssl.h"
#include "mio/mio.h"
#include "util/util.h"
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
typedef struct sm_st *sm_t;
typedef struct user_st *user_t;
typedef struct sess_st *sess_t;
typedef struct aci_st *aci_t;
typedef struct storage_st *storage_t;
typedef struct mm_st *mm_t;
#define uri_AUTH "jabber:iq:auth"
#define uri_REGISTER "jabber:iq:register"
#define uri_ROSTER "jabber:iq:roster"
#define uri_AGENTS "jabber:iq:agents"
#define uri_DELAY "jabber:x:delay"
#define uri_VERSION "jabber:iq:version"
#define uri_TIME "jabber:iq:time"
#define uri_VCARD "vcard-temp"
#define uri_PRIVATE "jabber:iq:private"
#define uri_BROWSE "jabber:iq:browse"
#define uri_EVENT "jabber:x:event"
#define uri_GATEWAY "jabber:iq:gateway"
#define uri_LAST "jabber:iq:last"
#define uri_EXPIRE "jabber:x:expire"
#define uri_PRIVACY "jabber:iq:privacy"
#define uri_SEARCH "jabber:iq:search"
#define uri_DISCO "http://jabber.org/protocol/disco"
#define uri_DISCO_ITEMS "http://jabber.org/protocol/disco#items"
#define uri_DISCO_INFO "http://jabber.org/protocol/disco#info"
#define uri_VACATION "http://jabber.org/protocol/vacation"
#define ns_AUTH (1)
#define ns_REGISTER (2)
#define ns_ROSTER (3)
#define ns_AGENTS (4)
#define ns_DELAY (5)
#define ns_VERSION (6)
#define ns_TIME (7)
#define ns_VCARD (8)
#define ns_PRIVATE (9)
#define ns_BROWSE (10)
#define ns_EVENT (11)
#define ns_GATEWAY (12)
#define ns_LAST (13)
#define ns_EXPIRE (14)
#define ns_PRIVACY (15)
#define ns_SEARCH (16)
#define ns_DISCO (17)
#define ns_DISCO_ITEMS (18)
#define ns_DISCO_INFO (19)
#define ns_VACATION (20)
typedef enum {
pkt_NONE = 0x00,
pkt_MESSAGE = 0x10,
pkt_PRESENCE = 0x20,
pkt_PRESENCE_UN = 0x21,
pkt_PRESENCE_INVIS = 0x22,
pkt_PRESENCE_PROBE = 0x24,
pkt_S10N = 0x40,
pkt_S10N_ED = 0x41,
pkt_S10N_UN = 0x42,
pkt_S10N_UNED = 0x44,
pkt_IQ = 0x80,
pkt_IQ_SET = 0x81,
pkt_IQ_RESULT = 0x82,
pkt_SESS = 0x100,
pkt_SESS_END = 0x101,
pkt_SESS_CREATE = 0x102,
pkt_SESS_DELETE = 0x104,
pkt_SESS_FAILED = 0x08,
pkt_SESS_MASK = 0x10f,
pkt_ERROR = 0x200
} pkt_type_t;
typedef enum {
route_NONE = 0x00,
route_UNICAST = 0x10,
route_BROADCAST = 0x11,
route_ADV = 0x20,
route_ADV_UN = 0x21,
route_ERROR = 0x40
} route_type_t;
typedef struct pkt_st {
sm_t sm;
sess_t source;
jid_t rto, rfrom;
route_type_t rtype;
pkt_type_t type;
jid_t to, from;
int ns;
int pri;
nad_t nad;
} *pkt_t;
typedef struct item_st {
jid_t jid;
char *name;
char **groups;
int ngroups;
int to, from;
int ask;
} *item_t;
struct sm_st {
char *id;
char *router_ip;
int router_port;
char *router_user;
char *router_pass;
char *router_pemfile;
mio_t mio;
sx_env_t sx_env;
sx_plugin_t sx_sasl;
sx_plugin_t sx_ssl;
sx_t router;
int fd;
xht users;
xht sessions;
xht xmlns;
xht features;
config_t config;
log_t log;
log_type_t log_type;
char *log_facility;
char *log_ident;
int retry_init;
int retry_lost;
int retry_sleep;
int retry_left;
prep_cache_t pc;
storage_t st;
mm_t mm;
xht acls;
char signature[2048];
int siglen;
int started;
int online;
};
struct user_st {
pool p;
sm_t sm;
jid_t jid;
xht roster;
sess_t sessions;
sess_t top;
time_t active;
void **module_data;
};
struct sess_st {
pool p;
user_t user;
jid_t jid;
char c2s[1024];
char sm_id[41];
char c2s_id[10];
pkt_t pres;
int available;
int invisible;
int pri;
jid_t A;
jid_t E;
void **module_data;
sess_t next;
};
extern sig_atomic_t sm_lost_router;
xht aci_load(sm_t sm);
int aci_check(xht acls, char *type, jid_t jid);
void aci_unload(xht acls);
int sm_sx_callback(sx_t s, sx_event_t e, void *data, void *arg);
int sm_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg);
void sm_timestamp(time_t t, char timestamp[18]);
void sm_c2s_action(sess_t dest, char *action, char *target);
void sm_signature(sm_t sm, char *str);
void dispatch(sm_t sm, pkt_t pkt);
pkt_t pkt_error(pkt_t pkt, int err);
pkt_t pkt_tofrom(pkt_t pkt);
pkt_t pkt_dup(pkt_t pkt, const char *to, const char *from);
pkt_t pkt_new(sm_t sm, nad_t nad);
void pkt_free(pkt_t pkt);
pkt_t pkt_create(sm_t sm, const char *elem, const char *type, const char *to, const char *from);
void pkt_id(pkt_t src, pkt_t dest);
void pkt_delay(pkt_t pkt, time_t t, const char *from);
void pkt_router(pkt_t pkt);
void pkt_sess(pkt_t pkt, sess_t sess);
int pres_trust(user_t user, jid_t jid);
void pres_roster(sess_t sess, item_t item);
void pres_update(sess_t sess, pkt_t pres);
void pres_error(sess_t sess, jid_t jid);
void pres_deliver(sess_t sess, pkt_t pres);
void pres_in(user_t user, pkt_t pres);
void pres_probe(user_t user);
void sess_route(sess_t sess, pkt_t pkt);
sess_t sess_start(sm_t sm, jid_t jid);
void sess_end(sess_t sess);
sess_t sess_match(user_t user, char *resource);
user_t user_load(sm_t sm, jid_t jid);
void user_free(user_t user);
int user_create(sm_t sm, jid_t jid);
void user_delete(sm_t sm, jid_t jid);
void feature_register(sm_t sm, char *feature);
void feature_unregister(sm_t sm, char *feature);
typedef enum {
mod_HANDLED,
mod_PASS
} mod_ret_t;
typedef enum {
chain_SESS_START,
chain_SESS_END,
chain_IN_SESS,
chain_IN_ROUTER,
chain_OUT_SESS,
chain_OUT_ROUTER,
chain_PKT_SM,
chain_PKT_USER,
chain_PKT_ROUTER,
chain_USER_LOAD,
chain_USER_CREATE,
chain_USER_DELETE
} mod_chain_t;
typedef struct module_st *module_t;
typedef struct mod_instance_st *mod_instance_t;
struct mm_st {
sm_t sm;
xht modules;
int nindex;
mod_instance_t *sess_start; int nsess_start;
mod_instance_t *sess_end; int nsess_end;
mod_instance_t *in_sess; int nin_sess;
mod_instance_t *in_router; int nin_router;
mod_instance_t *out_sess; int nout_sess;
mod_instance_t *out_router; int nout_router;
mod_instance_t *pkt_sm; int npkt_sm;
mod_instance_t *pkt_user; int npkt_user;
mod_instance_t *pkt_router; int npkt_router;
mod_instance_t *user_load; int nuser_load;
mod_instance_t *user_create; int nuser_create;
mod_instance_t *user_delete; int nuser_delete;
};
struct module_st {
mm_t mm;
char *name;
int index;
int init;
void *private;
int (*sess_start)(mod_instance_t mi, sess_t sess);
void (*sess_end)(mod_instance_t mi, sess_t sess);
mod_ret_t (*in_sess)(mod_instance_t mi, sess_t sess, pkt_t pkt);
mod_ret_t (*in_router)(mod_instance_t mi, pkt_t pkt);
mod_ret_t (*out_sess)(mod_instance_t mi, sess_t sess, pkt_t pkt);
mod_ret_t (*out_router)(mod_instance_t mi, pkt_t pkt);
mod_ret_t (*pkt_sm)(mod_instance_t mi, pkt_t pkt);
mod_ret_t (*pkt_user)(mod_instance_t mi, user_t user, pkt_t pkt);
mod_ret_t (*pkt_router)(mod_instance_t mi, pkt_t pkt);
int (*user_load)(mod_instance_t mi, user_t user);
int (*user_create)(mod_instance_t mi, jid_t jid);
void (*user_delete)(mod_instance_t mi, jid_t jid);
void (*free)(module_t mod);
};
struct mod_instance_st {
sm_t sm;
module_t mod;
int seq;
mod_chain_t chain;
char *arg;
};
mm_t mm_new(sm_t sm);
void mm_free(mm_t mm);
int mm_sess_start(mm_t mm, sess_t sess);
void mm_sess_end(mm_t mm, sess_t sess);
mod_ret_t mm_in_sess(mm_t mm, sess_t sess, pkt_t pkt);
mod_ret_t mm_in_router(mm_t mm, pkt_t pkt);
mod_ret_t mm_out_sess(mm_t mm, sess_t sess, pkt_t pkt);
mod_ret_t mm_out_router(mm_t mm, pkt_t pkt);
mod_ret_t mm_pkt_sm(mm_t mm, pkt_t pkt);
mod_ret_t mm_pkt_user(mm_t mm, user_t user, pkt_t pkt);
mod_ret_t mm_pkt_router(mm_t mm, pkt_t pkt);
int mm_user_load(mm_t mm, user_t user);
int mm_user_create(mm_t mm, jid_t jid);
void mm_user_delete(mm_t mm, jid_t jid);
typedef int (*module_init_fn)(mod_instance_t);
typedef enum {
os_type_BOOLEAN,
os_type_INTEGER,
os_type_STRING,
os_type_NAD,
os_type_UNKNOWN
} os_type_t;
typedef struct os_field_st {
char *key;
void *val;
os_type_t type;
} *os_field_t;
typedef struct os_st *os_t;
typedef struct os_object_st *os_object_t;
struct os_st {
pool p;
os_object_t head;
os_object_t tail;
int count;
os_object_t iter;
};
struct os_object_st {
os_t os;
xht hash;
os_object_t next;
os_object_t prev;
};
os_t os_new(void);
void os_free(os_t os);
int os_count(os_t os);
int os_iter_first(os_t os);
int os_iter_next(os_t os);
os_object_t os_iter_object(os_t os);
os_object_t os_object_new(os_t os);
void os_object_free(os_object_t o);
void os_object_put(os_object_t o, const char *key, const void *val, os_type_t type);
int os_object_get(os_t os, os_object_t o, const char *key, void **val, os_type_t type, os_type_t *ot);
int os_object_get_nad(os_t os, os_object_t o, const char *key, nad_t *val);
int os_object_get_str(os_t os, os_object_t o, const char *key, char **val);
int os_object_get_int(os_t os, os_object_t o, const char *key, int *val);
int os_object_get_bool(os_t os, os_object_t o, const char *key, int *val);
int os_object_get_time(os_t os, os_object_t o, const char *key, time_t *val);
void os_object_put_time(os_object_t o, const char *key, const time_t *val);
int os_object_iter_first(os_object_t o);
int os_object_iter_next(os_object_t o);
void os_object_iter_get(os_object_t o, char **key, void **val, os_type_t *type);
typedef enum {
st_SUCCESS,
st_FAILED,
st_NOTFOUND,
st_NOTIMPL
} st_ret_t;
typedef struct st_driver_st *st_driver_t;
struct storage_st {
sm_t sm;
xht drivers;
xht types;
st_driver_t default_drv;
};
struct st_driver_st {
storage_t st;
char *name;
void *private;
st_ret_t (*add_type)(st_driver_t drv, const char *type);
st_ret_t (*put)(st_driver_t drv, const char *type, const char *owner, os_t os);
st_ret_t (*get)(st_driver_t drv, const char *type, const char *owner, const char *filter, os_t *os);
st_ret_t (*delete)(st_driver_t drv, const char *type, const char *owner, const char *filter);
st_ret_t (*replace)(st_driver_t drv, const char *type, const char *owner, const char *filter, os_t os);
void (*free)(st_driver_t drv);
};
storage_t storage_new(sm_t sm);
void storage_free(storage_t st);
st_ret_t storage_add_type(storage_t st, const char *driver, const char *type);
st_ret_t storage_put(storage_t st, const char *type, const char *owner, os_t os);
st_ret_t storage_get(storage_t st, const char *type, const char *owner, const char *filter, os_t *os);
st_ret_t storage_delete(storage_t st, const char *type, const char *owner, const char *filter);
st_ret_t storage_replace(storage_t st, const char *type, const char *owner, const char *filter, os_t os);
typedef st_ret_t (*st_driver_init_fn)(st_driver_t);
typedef enum {
st_filter_type_PAIR,
st_filter_type_AND,
st_filter_type_OR,
st_filter_type_NOT
} st_filter_type_t;
typedef struct st_filter_st *st_filter_t;
struct st_filter_st {
pool p;
st_filter_type_t type;
char *key;
char *val;
st_filter_t sub;
st_filter_t next;
};
st_filter_t storage_filter(const char *filter);
int storage_match(st_filter_t filter, os_object_t o, os_t os);