Module: sip-router Branch: master Commit: f7be3b0588367081f1ed7224a74da59e284d53ab URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f7be3b05...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Mon Mar 31 00:55:06 2014 +0200
evapi: exported pv $evapi(key)
- key can be: * srcaddr - source ip of client connection * srcport - source port of client connection * msg - message received from client * conidx - internal index of client connection
---
modules/evapi/evapi_dispatch.c | 144 +++++++++++++++++++++++++++++++++++---- modules/evapi/evapi_dispatch.h | 7 ++ modules/evapi/evapi_mod.c | 11 +++- 3 files changed, 146 insertions(+), 16 deletions(-)
diff --git a/modules/evapi/evapi_dispatch.c b/modules/evapi/evapi_dispatch.c index 5a13ae4..fadf886 100644 --- a/modules/evapi/evapi_dispatch.c +++ b/modules/evapi/evapi_dispatch.c @@ -49,6 +49,12 @@ typedef struct _evapi_client { char src_addr[EVAPI_IPADDR_SIZE]; } evapi_client_t;
+typedef struct _evapi_env { + int eset; + int conidx; + str msg; +} evapi_env_t; + #define EVAPI_MAX_CLIENTS 8 static evapi_client_t _evapi_clients[EVAPI_MAX_CLIENTS];
@@ -60,7 +66,16 @@ typedef struct _evapi_evroutes {
static evapi_evroutes_t _evapi_rts;
-static int _evapi_con_idx = -1; +static evapi_env_t _evapi_env_data; + +/** + * + */ +void evapi_env_reset(void) +{ + memset(&_evapi_env_data, 0, sizeof(evapi_env_t)); + _evapi_env_data.conidx = -1; +}
/** * @@ -68,6 +83,7 @@ static int _evapi_con_idx = -1; void evapi_init_event_routes(void) { memset(&_evapi_rts, 0, sizeof(evapi_evroutes_t)); + evapi_env_reset();
_evapi_rts.con_new = route_get(&event_rt, "evapi:connection-new"); if (_evapi_rts.con_new < 0 || event_rt.rlist[_evapi_rts.con_new] == NULL) @@ -83,25 +99,25 @@ void evapi_init_event_routes(void) /** * */ -int evapi_run_cfg_route(int conidx, int rt) +int evapi_run_cfg_route(int rt) { int backup_rt; struct run_act_ctx ctx; sip_msg_t *fmsg;
- if(conidx<0) + if(_evapi_env_data.eset==0) { + LM_ERR("evapi env not set\n"); return -1; + }
if(rt<0) return 0;
fmsg = faked_msg_next(); backup_rt = get_route_type(); - _evapi_con_idx = conidx; set_route_type(REQUEST_ROUTE); init_run_actions_ctx(&ctx); run_top_route(event_rt.rlist[rt], fmsg, 0); - _evapi_con_idx = -1; set_route_type(backup_rt); return 0; } @@ -111,13 +127,13 @@ int evapi_run_cfg_route(int conidx, int rt) */ int evapi_cfg_close_connection(void) { - if(_evapi_con_idx<0 || _evapi_con_idx>=EVAPI_MAX_CLIENTS) + if(_evapi_env_data.conidx<0 || _evapi_env_data.conidx>=EVAPI_MAX_CLIENTS) return -1; - if(_evapi_clients[_evapi_con_idx].connected==1 - && _evapi_clients[_evapi_con_idx].sock > 0) { - close(_evapi_clients[_evapi_con_idx].sock); - _evapi_clients[_evapi_con_idx].connected = 0; - _evapi_clients[_evapi_con_idx].sock = 0; + if(_evapi_clients[_evapi_env_data.conidx].connected==1 + && _evapi_clients[_evapi_env_data.conidx].sock > 0) { + close(_evapi_clients[_evapi_env_data.conidx].sock); + _evapi_clients[_evapi_env_data.conidx].connected = 0; + _evapi_clients[_evapi_env_data.conidx].sock = 0; return 0; } return -2; @@ -194,7 +210,7 @@ void evapi_recv_client(struct ev_loop *loop, struct ev_io *watcher, int revents) }
/* read message from client */ - rlen = recv(watcher->fd, rbuffer, CLIENT_BUFFER_SIZE, 0); + rlen = recv(watcher->fd, rbuffer, CLIENT_BUFFER_SIZE-1, 0);
if(rlen < 0) { LM_ERR("cannot read the client message\n"); @@ -213,7 +229,10 @@ void evapi_recv_client(struct ev_loop *loop, struct ev_io *watcher, int revents)
if(rlen == 0) { /* client is gone */ - evapi_run_cfg_route(i, _evapi_rts.con_closed); + _evapi_env_data.eset = 1; + _evapi_env_data.conidx = i; + evapi_run_cfg_route(_evapi_rts.con_closed); + evapi_env_reset(); _evapi_clients[i].connected = 0; _evapi_clients[i].sock = 0; ev_io_stop(loop, watcher); @@ -223,10 +242,17 @@ void evapi_recv_client(struct ev_loop *loop, struct ev_io *watcher, int revents) return; }
+ rbuffer[rlen] = '\0'; + LM_NOTICE("{%d} [%s:%d] - received [%.*s]\n", i, _evapi_clients[i].src_addr, _evapi_clients[i].src_port, (int)rlen, rbuffer); - evapi_run_cfg_route(i, _evapi_rts.msg_received); + _evapi_env_data.conidx = i; + _evapi_env_data.msg.s = rbuffer; + _evapi_env_data.msg.len = rlen; + _evapi_env_data.eset = 1; + evapi_run_cfg_route(_evapi_rts.msg_received); + evapi_env_reset(); }
/** @@ -294,7 +320,10 @@ void evapi_accept_client(struct ev_loop *loop, struct ev_io *watcher, int revent LM_DBG("new connection - pos[%d] from: [%s:%d]\n", i, _evapi_clients[i].src_addr, _evapi_clients[i].src_port);
- evapi_run_cfg_route(i, _evapi_rts.con_new); + _evapi_env_data.conidx = i; + _evapi_env_data.eset = 1; + evapi_run_cfg_route(_evapi_rts.con_new); + evapi_env_reset();
if(_evapi_clients[i].connected == 0) return; @@ -489,3 +518,88 @@ int evapi_relay(str *event, str *data) return 0; } #endif + +/** + * + */ +int pv_parse_evapi_name(pv_spec_t *sp, str *in) +{ + if(sp==NULL || in==NULL || in->len<=0) + return -1; + + switch(in->len) + { + case 3: + if(strncmp(in->s, "msg", 3)==0) + sp->pvp.pvn.u.isname.name.n = 1; + else goto error; + break; + case 6: + if(strncmp(in->s, "conidx", 6)==0) + sp->pvp.pvn.u.isname.name.n = 0; + else goto error; + break; + case 7: + if(strncmp(in->s, "srcaddr", 7)==0) + sp->pvp.pvn.u.isname.name.n = 2; + else if(strncmp(in->s, "srcport", 7)==0) + sp->pvp.pvn.u.isname.name.n = 3; + else goto error; + break; + default: + goto error; + } + sp->pvp.pvn.type = PV_NAME_INTSTR; + sp->pvp.pvn.u.isname.type = 0; + + return 0; + +error: + LM_ERR("unknown PV msrp name %.*s\n", in->len, in->s); + return -1; +} + +/** + * + */ +int pv_get_evapi(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) +{ + if(param==NULL || res==NULL) + return -1; + + if(_evapi_env_data.conidx<0 || _evapi_env_data.conidx>=EVAPI_MAX_CLIENTS) + return pv_get_null(msg, param, res); + + if(_evapi_clients[_evapi_env_data.conidx].connected==0 + && _evapi_clients[_evapi_env_data.conidx].sock <= 0) + return pv_get_null(msg, param, res); + + switch(param->pvn.u.isname.name.n) + { + case 0: + return pv_get_sintval(msg, param, res, _evapi_env_data.conidx); + case 1: + if(_evapi_env_data.msg.s==NULL) + return pv_get_null(msg, param, res); + return pv_get_strval(msg, param, res, &_evapi_env_data.msg); + case 2: + return pv_get_strzval(msg, param, res, + _evapi_clients[_evapi_env_data.conidx].src_addr); + case 3: + return pv_get_sintval(msg, param, res, + _evapi_clients[_evapi_env_data.conidx].src_port); + default: + return pv_get_null(msg, param, res); + } + + return 0; +} + +/** + * + */ +int pv_set_evapi(sip_msg_t *msg, pv_param_t *param, int op, + pv_value_t *val) +{ + return 0; +} diff --git a/modules/evapi/evapi_dispatch.h b/modules/evapi/evapi_dispatch.h index 5db3bd7..4614beb 100644 --- a/modules/evapi/evapi_dispatch.h +++ b/modules/evapi/evapi_dispatch.h @@ -23,6 +23,8 @@ #ifndef _EVAPI_DISPATCH_ #define _EVAPI_DISPATCH_
+#include "../../pvar.h" + int evapi_init_notify_sockets(void);
void evapi_close_notify_sockets_child(void); @@ -37,4 +39,9 @@ int evapi_relay(str *evdata);
void evapi_init_event_routes(void);
+int pv_parse_evapi_name(pv_spec_t *sp, str *in); +int pv_get_evapi(sip_msg_t *msg, pv_param_t *param, pv_value_t *res); +int pv_set_evapi(sip_msg_t *msg, pv_param_t *param, int op, + pv_value_t *val); + #endif diff --git a/modules/evapi/evapi_mod.c b/modules/evapi/evapi_mod.c index 089be86..3cef3ca 100644 --- a/modules/evapi/evapi_mod.c +++ b/modules/evapi/evapi_mod.c @@ -34,6 +34,7 @@ #include "../../pvar.h" #include "../../mem/shm_mem.h" #include "../../mod_fix.h" +#include "../../pvar.h" #include "../../cfg/cfg_struct.h" #include "../../lib/kcore/faked_msg.h"
@@ -72,6 +73,14 @@ static param_export_t params[]={ {0, 0, 0} };
+static pv_export_t mod_pvs[] = { + { {"evapi", (sizeof("evapi")-1)}, PVT_OTHER, pv_get_evapi, + pv_set_evapi, pv_parse_evapi_name, 0, 0, 0}, + + { {0, 0}, 0, 0, 0, 0, 0, 0, 0 } +}; + + struct module_exports exports = { "evapi", DEFAULT_DLFLAGS, /* dlopen flags */ @@ -79,7 +88,7 @@ struct module_exports exports = { params, 0, 0, /* exported MI functions */ - 0, /* exported pseudo-variables */ + mod_pvs, /* exported pseudo-variables */ 0, /* extra processes */ mod_init, /* module initialization function */ 0, /* response function */