1
0
Fork 0

Added admin interface for mmsbox

This commit is contained in:
bagyenda 2008-09-02 11:07:16 +00:00
parent 30d9e2c0d4
commit 1a3aa4c9aa
6 changed files with 437 additions and 100 deletions

View File

@ -1,3 +1,5 @@
2008-09-02 P. A. Bagyenda <bagyenda@dsmagic.com>
* Added admin interface to mmsbox (can now start/stop and see status of any mmsc connection)
2008-09-01 P. A. Bagyenda <bagyenda@dsmagic.com>
* Rolled mmsrelay + mmsproxy into one item (for easier online management)
2008-08-29 P. A. Bagyenda <bagyenda@dsmagic.com>

View File

@ -100,6 +100,14 @@ SINGLE_GROUP(mbuni,
OCTSTR(mmsbox-mt-filter-library)
OCTSTR(mmsbox-mt-always-multipart)
OCTSTR(mmsbox-admin-port)
OCTSTR(mmsc-admin-port)
OCTSTR(admin-port-ssl)
OCTSTR(admin-password)
OCTSTR(admin-allow-ip)
OCTSTR(admin-deny-ip)
)
MULTI_GROUP(mmsproxy,

View File

@ -140,7 +140,7 @@ int mmsbox_send_report(Octstr *from, char *report_type,
}
/* These functions are very similar to those in mmsproxy */
static void mm7soap_receive(MmsBoxHTTPClientInfo *h)
static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
{
MSoapMsg_t *mreq = NULL, *mresp = NULL;
@ -167,6 +167,7 @@ static void mm7soap_receive(MmsBoxHTTPClientInfo *h)
if (!mreq) {
mresp = mm7_make_resp(NULL, MM7_SOAP_FORMAT_CORRUPT, NULL,1);
status = 4000;
goto done;
}
@ -315,6 +316,7 @@ static void mm7soap_receive(MmsBoxHTTPClientInfo *h)
default:
mresp = mm7_make_resp(mreq, MM7_SOAP_UNSUPPORTED_OPERATION, NULL,1);
status = MM7_SOAP_UNSUPPORTED_OPERATION;
break;
}
@ -342,9 +344,11 @@ static void mm7soap_receive(MmsBoxHTTPClientInfo *h)
mm7_soap_destroy(mreq);
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
octstr_destroy(mmc_id);
return MM7_SOAP_STATUS_OK(status) ? 0 : -1;
}
static void mm7eaif_receive(MmsBoxHTTPClientInfo *h)
static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
{
MmsMsg *m = NULL;
List *mh = NULL;
@ -547,7 +551,9 @@ static void mm7eaif_receive(MmsBoxHTTPClientInfo *h)
octstr_destroy(mmc_id);
http_destroy_headers(mh);
mms_destroy(m);
mms_destroy(m);
return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1;
}
@ -557,6 +563,7 @@ static void dispatch_mm7_recv(List *rl)
MmsBoxHTTPClientInfo *h;
while ((h = gwlist_consume(rl)) != NULL) {
int ret = -1;
MmscGrp *m = h->m;
if (auth_check(m->incoming.user,
m->incoming.pass,
@ -570,10 +577,16 @@ static void dispatch_mm7_recv(List *rl)
info(0, "MMSBox: Auth failed, incoming connection, MMC group=[%s]",
m->id ? octstr_get_cstr(m->id) : "(none)");
} else if (h->m->type == SOAP_MMSC)
mm7soap_receive(h);
ret = mm7soap_receive(h);
else
mm7eaif_receive(h);
ret = mm7eaif_receive(h);
h->m->last_pdu = time(NULL);
if (ret == 0)
h->m->mo_pdus++;
else
h->m->mo_errors++;
free_mmsbox_http_clientInfo(h, 1);
}
}
@ -583,11 +596,12 @@ void mmsc_receive_func(MmscGrp *m)
int i;
MmsBoxHTTPClientInfo h = {NULL};
List *mmsc_incoming_reqs = gwlist_create();
long *thids = gw_malloc((maxthreads + 1)*sizeof thids[0]);
gwlist_add_producer(mmsc_incoming_reqs);
for (i = 0; i<maxthreads; i++)
gwthread_create((gwthread_func_t *)dispatch_mm7_recv, mmsc_incoming_reqs);
thids[i] = gwthread_create((gwthread_func_t *)dispatch_mm7_recv, mmsc_incoming_reqs);
h.m = m;
while(rstop == 0 &&
@ -628,12 +642,17 @@ void mmsc_receive_func(MmscGrp *m)
free_mmsbox_http_clientInfo(&h, 0);
}
debug("proxy", 0, "MMSBox: MM7 receiver Shutting down...");
debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down...", octstr_get_cstr(m->id));
gwlist_remove_producer(mmsc_incoming_reqs);
gwthread_join_every((void *)dispatch_mm7_recv);
gwlist_destroy(mmsc_incoming_reqs, NULL);
debug("proxy", 0, "MMSBox: MM7 receiver Shutting down complete.");
for (i = 0; i<maxthreads; i++)
if (thids[i] >= 0)
gwthread_join(thids[i]);
gwlist_destroy(mmsc_incoming_reqs, NULL);
gw_free(thids);
debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down complete.", octstr_get_cstr(m->id));
}
@ -984,7 +1003,11 @@ static int sendMsg(MmsEnvelope *e)
e->hdrs,
&new_msgid,
&err);
if (res == MMS_SEND_OK)
mmc->mt_pdus++;
else
mmc->mt_errors++;
mmc->last_pdu = time(NULL);
return_mmsc_conn(mmc); /* important. */
done:
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {

View File

@ -574,7 +574,6 @@ int main(int argc, char *argv[])
{
Octstr *fname;
int cfidx;
mCfg *cfg;
long qthread = 0, sthread = 0;
@ -588,11 +587,9 @@ int main(int argc, char *argv[])
fname = octstr_imm("mbuni.conf");
else
fname = octstr_create(argv[cfidx]);
cfg = mms_cfg_read(fname);
if (cfg == NULL)
panic(0, "Couldn't read configuration from '%s'.", octstr_get_cstr(fname));
if (mms_load_mmsbox_settings(fname,(gwthread_func_t *)mmsc_receive_func) < 0)
panic(0, "Configuration file loading failed, file: %s", octstr_get_cstr(fname));
octstr_destroy(fname);
@ -600,10 +597,6 @@ int main(int argc, char *argv[])
info(0, " " MM_NAME " MMSBox version %s starting", MMSC_VERSION);
mms_load_mmsbox_settings(cfg,(gwthread_func_t *)mmsc_receive_func);
mms_cfg_destroy(cfg);
signal(SIGHUP, relog_now);
signal(SIGTERM, quit_now);
signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for nothing*/
@ -622,7 +615,6 @@ int main(int argc, char *argv[])
info(0, "Shutdown started..");
mmsbox_cleanup_settings();
sleep(2);
/* Wait for the sender thread, then quit. */
gwthread_join(qthread); /* Wait for it to die... */

View File

@ -43,30 +43,51 @@ MmsBoxResolverFuncStruct *rfs; /* resolver functions. */
void *rfs_data;
Octstr *rfs_settings;
static mCfg *cfg; /* Config. */
static Dict *mmscs = NULL; /* MMSC's indexed by ID. */
static List *mmsc_del_list = NULL; /* List of items to be deleted. */
/* admin handler variables. */
static long admin_port;
static long admin_thread = -1;
static Octstr *admin_pass = NULL;
static Octstr *admin_allow_ip = NULL;
static Octstr *admin_deny_ip = NULL;
static gwthread_func_t *mmsc_receiver_func;
struct SendMmsPortInfo sendmms_port;
struct MmsBoxMTfilter *mt_filter = NULL;
static void free_mmsc_struct (MmscGrp *m);
static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func);
static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc);
int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
static void admin_handler(void *unused);
int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
{
mCfgGrp *grp = mms_cfg_get_single(cfg, octstr_imm("mbuni"));
mCfgGrp *cgrp = mms_cfg_get_single(cfg, octstr_imm("core"));
mCfgGrp *grp;
mCfgGrp *cgrp;
Octstr *gdir = NULL, *s;
int send_port_ssl = 0;
int send_port_ssl = 0, admin_port_ssl = 0;
List *l;
int i, n, xx;
void *catchall = NULL;
if (grp == NULL)
panic(0,"Missing required group `mbuni' in config file!");
if ((cfg = mms_cfg_read(fname)) == NULL) {
error(0, "Couldn't read configuration from '%s'.", octstr_get_cstr(fname));
return -1;
}
grp = mms_cfg_get_single(cfg, octstr_imm("mbuni"));
cgrp = mms_cfg_get_single(cfg, octstr_imm("core"));
if (grp == NULL) {
error(0,"Missing required group `mbuni' in config file!");
return -1;
}
mms_load_core_settings(cfg, cgrp);
@ -201,10 +222,29 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
}
gwlist_destroy(l, NULL);
/* Get mmsc list. */
mmsc_receiver_func = mmsc_handler_func; /* save it. */
/* Start MMSCs. */
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
for (i = 0, n = gwlist_len(l); i < n; i++)
start_mmsc_from_conf(cfg, gwlist_get(l, i), mmsc_handler_func);
for (i = 0, n = gwlist_len(l); i < n; i++) {
List *errors = gwlist_create();
List *warnings = gwlist_create();
Octstr *x;
start_mmsc_from_conf(cfg, gwlist_get(l, i), mmsc_handler_func, errors, warnings);
while ((x = gwlist_extract_first(errors)) != NULL) {
error(0, "%s", octstr_get_cstr(x));
octstr_destroy(x);
}
while ((x = gwlist_extract_first(warnings)) != NULL) {
warning(0, "%s", octstr_get_cstr(x));
octstr_destroy(x);
}
gwlist_destroy(errors, NULL);
gwlist_destroy(warnings, NULL);
}
gwlist_destroy(l, NULL);
@ -348,13 +388,37 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
gwlist_append(mms_services, m);
}
/* Finally load admin-port config and start the thingie */
mms_cfg_get_int(cfg, grp, octstr_imm("mmsbox-admin-port"), &admin_port);
#ifdef HAVE_LIBSSL
mms_cfg_get_bool(cfg, grp, octstr_imm("admin-port-ssl"), &admin_port_ssl);
#endif
admin_pass = mms_cfg_get(cfg, grp, octstr_imm("admin-password"));
admin_allow_ip = mms_cfg_get(cfg, grp, octstr_imm("admin-allow-ip"));
admin_deny_ip = mms_cfg_get(cfg, grp, octstr_imm("admin-deny-ip"));
if (admin_port > 0 &&
http_open_port(admin_port, admin_port_ssl)< 0)
error(0, "Failed to start admin server on port %d: %s",
(int)admin_port, strerror(errno));
else if (admin_port > 0 &&
(admin_thread = gwthread_create((gwthread_func_t *)admin_handler, NULL)) < 0) {
error(0, "Failed to start admin server thread: %s",
strerror(errno));
http_close_port(admin_port);
} else if (admin_pass == NULL)
warning(0, "Empty or no password supplied for admin port. All requests will be allowed!");
gwlist_destroy(l, NULL);
octstr_destroy(gdir);
return 0;
}
/* do nothing func. */
/* do nothing func: Vital it returns 0! */
static int do_nothing_func (void) {return 0;}
static MmsBoxMmscFuncs dummy_mmsc_funcs = {
@ -363,7 +427,62 @@ static MmsBoxMmscFuncs dummy_mmsc_funcs = {
(void *)do_nothing_func
};
void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func)
#define ERROR(fmt,...) do {if (errors) gwlist_append(errors, octstr_format((fmt), ##__VA_ARGS__));} while(0)
#define WARNING(fmt,...) do {if (warnings) gwlist_append(warnings, octstr_format((fmt), ##__VA_ARGS__));}while(0)
static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc)
{
if (mmc->type == CUSTOM_MMSC && mmc->fns
&& mmc->custom_started) {
mmc->fns->stop_conn(mmc->data);
mmc->custom_started = 0;
} else if (mmc->incoming.port > 0) {
http_close_port(mmc->incoming.port);
if (mmc->threadid >= 0)
gwthread_join(mmc->threadid);
mmc->threadid = -1;
}
info(0, "Shutdown for mmsc [%s] complete", octstr_get_cstr(mmc->id));
}
static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func,
List *errors, List *warnings)
{
if (m->type == CUSTOM_MMSC) {
if (m->fns->start_conn(m, qfs, unified_prefix, strip_prefixes, &m->data) != 0) {
WARNING("MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id));
m->custom_started = 0;
} else
m->custom_started = 1;
} else {
if (m->incoming.port > 0 &&
http_open_port(m->incoming.port, m->incoming.ssl) < 0) {
WARNING("MMSBox: Failed to start HTTP server on receive port for "
" MMSC %s, port %ld: %s!",
octstr_get_cstr(m->id), m->incoming.port,
strerror(errno));
m->incoming.port = 0; /* so we don't listen on it. */
}
if (mmsc_handler_func && m->incoming.port > 0) { /* Only start threads if func passed and ... */
if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0)
ERROR("MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!",
octstr_get_cstr(m->id), strerror(errno));
} else
m->threadid = -1;
}
info(0, "Startup for mmsc [%s] complete", octstr_get_cstr(m->id));
}
MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func,
List *warnings, List *errors)
{
MmscGrp *m = gw_malloc(sizeof *m);
@ -373,14 +492,14 @@ void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_f
Octstr *s;
memset(m, 0, sizeof *m);
m->id = _mms_cfg_getx(cfg, x, octstr_imm("id"));
if (octstr_len(m->id) < 1) {
error(0,"mmsbox.mmsc_config: Missing required field value `id' in config file!");
ERROR("mmsbox.mmsc_config: Missing required field value `id' in config file!");
octstr_destroy(m->id);
gw_free(m);
return;
return NULL;
}
m->group_id = mms_cfg_get(cfg, x, octstr_imm("group-id"));
@ -432,7 +551,7 @@ void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_f
m->fns = &dummy_mmsc_funcs;
}
} else
warning(0, "MMSBox: Unknown MMSC type [%s]!",
WARNING("MMSBox: Unknown MMSC type [%s]!",
octstr_get_cstr(type));
if ((xver = _mms_cfg_getx(cfg, x, octstr_imm("mm7-version"))) != NULL &&
octstr_len(xver) > 0)
@ -468,11 +587,11 @@ void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_f
if (mt_filter)
m->use_mt_filter = (mt_filter->init(m->mmsc_url, m->id, s) == 1);
else
panic(0, "MMSBox: mt-filter-params set for MMSC[%s] but no MT-filter lib "
ERROR("MMSBox: mt-filter-params set for MMSC[%s] but no MT-filter lib "
"specified!",
octstr_get_cstr(m->id));
if (!m->use_mt_filter)
warning(0, "MMSBox: MT MMS filter turned off for MMSC[%s]. Init failed",
WARNING( "MMSBox: MT MMS filter turned off for MMSC[%s]. Init failed",
octstr_get_cstr(m->id));
octstr_destroy(s);
} else
@ -482,77 +601,38 @@ void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_f
mms_cfg_get_bool(cfg, x, octstr_imm("reroute-add-sender-to-subject"), &m->reroute_mod_subject);
m->reroute_mmsc_id = mms_cfg_get(cfg, x, octstr_imm("reroute-mmsc-id"));
if (m->reroute_mmsc_id != NULL && m->reroute == 0)
warning(0, "MMSBox: reroute-mmsc-id parameter set but reroute=false!");
WARNING("MMSBox: reroute-mmsc-id parameter set but reroute=false!");
mms_cfg_get_bool(cfg, x, octstr_imm("no-sender-address"), &m->no_senderaddress);
m->mutex = mutex_create();
m->incoming.ssl = ssl;
m->start_time = time(NULL);
/* finally start the thingie. */
mmsbox_start_mmsc_conn(m, mmsc_handler_func);
mmsbox_start_mmsc_conn(m, mmsc_handler_func, errors, warnings);
if (dict_put_once(mmscs, m->id, m) == 0) {
error(0, "Failed to load mmsc <%s>. ID is not unique!", octstr_get_cstr(m->id));
WARNING("Failed to load mmsc <%s>. ID is not unique!", octstr_get_cstr(m->id));
mmsbox_stop_mmsc_conn_real(m);
free_mmsc_struct(m);
}
}
static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func)
{
if (m->type == CUSTOM_MMSC) {
if (m->fns->start_conn(m, qfs, unified_prefix, strip_prefixes, &m->data) != 0) {
warning(0, "MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id));
m->custom_started = 0;
} else
m->custom_started = 1;
} else {
if (m->incoming.port > 0 &&
http_open_port(m->incoming.port, m->incoming.ssl) < 0) {
warning(0, "MMSBox: Failed to start HTTP server on receive port for "
" MMSC %s, port %ld: %s!",
octstr_get_cstr(m->id), m->incoming.port,
strerror(errno));
m->incoming.port = 0; /* so we don't listen on it. */
}
if (mmsc_handler_func && m->incoming.port > 0) { /* Only start threads if func passed and ... */
if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0)
error(0, "MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!",
octstr_get_cstr(m->id), strerror(errno));
} else
m->threadid = -1;
m = NULL;
}
info(0, "Startup for mmsc [%s] complete", octstr_get_cstr(m->id));
return m;
}
static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc)
{
if (mmc->type == CUSTOM_MMSC && mmc->fns
&& mmc->custom_started) {
mmc->fns->stop_conn(mmc->data);
mmc->custom_started = 0;
} else if (mmc->incoming.port > 0) {
http_close_port(mmc->incoming.port);
if (mmc->threadid >= 0)
gwthread_join(mmc->threadid);
mmc->threadid = -1;
}
info(0, "Shutdown for mmsc [%s] complete", octstr_get_cstr(mmc->id));
}
void mmsbox_stop_mmsc_conn(Octstr *mmc_id)
int mmsbox_stop_mmsc_conn(Octstr *mmc_id)
{
MmscGrp *mmc = dict_remove(mmscs, mmc_id); /* remove it so no one else can get it. */
if (mmc == NULL)
return;
return -1;
mmsbox_stop_mmsc_conn_real(mmc);
mmc->delete_after = time(NULL) + 5*60; /* delete after 5 minutes. */
gwlist_append(mmsc_del_list, mmc); /* to be deleted later. */
return 0;
}
void mmsbox_stop_all_mmsc_conn(void)
@ -663,6 +743,18 @@ void mmsbox_settings_cleanup(void)
{
delete_stale_mmsc(1);
/* eventually we will destroy the object. For now, we only cleanup queue module. */
if (qfs)
qfs->mms_cleanup_queue_module();
if (admin_port > 0) {
http_close_port(admin_port);
gwthread_join(admin_thread);
info(0, "MmsBox: Admin port on %d, shutdown", (int)admin_port);
}
mms_cfg_destroy(cfg); /* only delete at end of session. */
/* More cleanups to follow. */
}
@ -736,11 +828,223 @@ Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
return 0;
}
void mmsbox_cleanup_settings(void)
static void append_mmsc_status(Octstr *rbody, MmscGrp *m, List *warnings)
{
/* eventually we will destroy the object. For now, we only cleanup queue module. */
if (qfs)
qfs->mms_cleanup_queue_module();
time_t t = time(NULL);
int i, n;
unsigned long tdiff;
char lbuf[128], ubuf[128], tmp[64], xport[32];
char *typ;
if (m->type == SOAP_MMSC)
typ = "SOAP";
else if (m->type == EAIF_MMSC)
typ = "EAIF";
else if (m->type == CUSTOM_MMSC)
typ = "CUSTOM";
else
typ = "none";
if (m->last_pdu > 0) {
struct tm tm = gw_localtime(m->last_pdu);
gw_strftime(lbuf,sizeof lbuf, "%x %X", &tm);
} else
strcpy(lbuf, "n/a");
/* Compute uptime */
tdiff = t - m->start_time;
if (tdiff >= 24*3600) {/* we have some days */
sprintf(ubuf, "%ld days", tdiff/(24*3600));
tdiff %= 24*3600;
} else
ubuf[0] = 0;
if (tdiff >= 3600) {
long x = tdiff/3600;
sprintf(tmp, "%s%ld hrs", ubuf[0] ? " " : "", x);
strcat(ubuf, tmp);
tdiff %= 3600;
}
if (tdiff >= 60) {
sprintf(tmp, "%s%ld mins", ubuf[0] ? " " : "", tdiff/60);
strcat(ubuf, tmp);
tdiff %= 60;
}
if (tdiff > 0) {
sprintf(tmp, "%s%ld secs", ubuf[0] ? " " : "", tdiff);
strcat(ubuf, tmp);
}
if (m->type != CUSTOM_MMSC)
sprintf(xport, "%d", (int)m->incoming.port);
else
sprintf(xport, "n/a");
octstr_format_append(rbody, "<Mmsc id=\"%S\" type=\"%s\">\n "
"<Port>%s</Port>\n"
"<Group>%S</Group>\n"
"<Throughput>%.4f</Throughput>\n"
"<Reroute>%s</Reroute>\n"
"<Reroute-MMSC-ID>%S</Reroute-MMSC-ID>\n"
"<Stats>\n"
"<Uptime>%s</Uptime>\n"
"<LastPDU>%s</LastPDU>\n"
"<MT><PDUS>%ld</PDUS><ERRORS>%ld</ERRORS></MT>\n"
"<MO><PDUS>%ld</PDUS><ERRORS>%ld</ERRORS></MO>\n"
"</Stats>\n",
m->id,
typ,
xport,
m->group_id ? m->group_id : octstr_imm("n/a"),
m->throughput,
m->reroute ? "true" : "false",
m->reroute_mmsc_id ? m->reroute_mmsc_id : octstr_imm("N/A"),
ubuf,
lbuf,
(long)m->mt_pdus, (long)m->mt_errors,
(long)m->mo_pdus, (long)m->mo_errors);
for (i = 0, n = gwlist_len(warnings); i<n; i++)
octstr_format_append(rbody, "<Warning>%S</Warning>\n", gwlist_get(warnings, i));
octstr_append_cstr(rbody, "</Mmsc>\n");
}
static void admin_handler(void *unused)
{
HTTPClient *client;
Octstr *ip;
List *headers;
Octstr *url;
Octstr *body;
List *cgivars;
Octstr *pass;
Octstr *cmd;
info(0, "MmsBox: Admin Interface -- startup on port %d", (int)admin_port);
while((client = http_accept_request(admin_port,
&ip, &url, &headers,
&body, &cgivars)) != NULL) {
int flg = -1;
Octstr *rbody = NULL;
int rstatus = HTTP_OK;
if (!(flg = is_allowed_ip(admin_allow_ip, admin_deny_ip, ip)) ||
((pass = http_cgi_variable(cgivars, "password")) == NULL && admin_pass != NULL) ||
(admin_pass && octstr_compare(pass, admin_pass) != 0)) {
error(0, "MmsBox: Improper access to mmsbox admin interface from IP[%s]: %s",
octstr_get_cstr(ip),
flg ? "Invalid/empty password" : "IP not allowed");
if (flg) {/* means it is allowed by IP */
rstatus = HTTP_UNAUTHORIZED;
rbody = octstr_imm("Auth failed");
}
} else if ((cmd = http_cgi_variable(cgivars, "command")) == NULL) {
rbody = octstr_imm("Missing Command Parameter");
rstatus = HTTP_BAD_REQUEST;
} else {
Octstr *mmc_id = http_cgi_variable(cgivars, "mmsc-id");
List *l = NULL;
rbody = octstr_create("<?xml version='1.0'?>\n");
/* Command is one of: status, start, stop.
* mmsc-id is either empty (meaning ALL) or an ID of an existing MMSC connection.
*/
if (octstr_str_case_compare(cmd, "start") == 0) {
mCfgGrp *m;
if (mmc_id == NULL)
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
else if ((m = mms_get_multi_by_field(cfg,
octstr_imm("mmsc"),
octstr_imm("id"),
mmc_id)) != NULL) {
l = gwlist_create();
gwlist_append(l, m);
}
/* Start MMSCs. */
while ((m = gwlist_extract_first(l)) != NULL) {
List *e = gwlist_create();
List *w = gwlist_create();
Octstr *x;
MmscGrp *mc = start_mmsc_from_conf(cfg, m, mmsc_receiver_func, e, w);
if (mc != NULL)
append_mmsc_status(rbody, mc, w);
else if (gwlist_len(e) > 0)
while ((x = gwlist_extract_first(e)) != NULL) {
octstr_format_append(rbody,
"<Start-Mmsc><Error>%S</Error></Start-Mmsc>\n",
x);
octstr_destroy(x);
}
gwlist_destroy(e, (void *)octstr_destroy);
gwlist_destroy(w, (void *)octstr_destroy);
}
} else if (octstr_str_case_compare(cmd, "stop") == 0) {
Octstr *x;
if (mmc_id == NULL)
l = dict_keys(mmscs);
else {
l = gwlist_create();
gwlist_append(l, octstr_duplicate(mmc_id));
}
while ((x = gwlist_extract_first(l)) != NULL) {
int ret = mmsbox_stop_mmsc_conn(x);
octstr_format_append(rbody,
"<Stop-Mmsc><%s/></Stop-Mmsc>\n",
ret == 0 ? "Success" : "Failed");
octstr_destroy(x);
}
} else if (octstr_str_case_compare(cmd, "status") == 0) {
Octstr *x;
MmscGrp *mc;
if (mmc_id == NULL)
l = dict_keys(mmscs);
else {
l = gwlist_create();
gwlist_append(l, octstr_duplicate(mmc_id));
}
while ((x = gwlist_extract_first(l)) != NULL) {
if ((mc = dict_get(mmscs, x)) != NULL)
append_mmsc_status(rbody, mc, NULL);
octstr_destroy(x);
}
}
gwlist_destroy(l, NULL);
}
if (rbody) {
List *rh = http_create_empty_headers();
http_header_add(rh, "Content-Type", "text/xml");
http_send_reply(client, rstatus, rh, rbody);
http_destroy_headers(rh);
} else
http_close_client(client);
octstr_destroy(rbody);
octstr_destroy(ip);
octstr_destroy(url);
octstr_destroy(body);
http_destroy_cgiargs(cgivars);
http_destroy_headers(headers);
}
info(0, "MmsBox: Admin Interface -- shuttind down on port %d", (int)admin_port);
}
void free_mmsbox_http_clientInfo(MmsBoxHTTPClientInfo *h, int freeh)

View File

@ -49,6 +49,14 @@ typedef struct MmscGrp {
void *data; /* data for above module. */
int custom_started; /* set to 1 if custom mmc started. */
unsigned long mt_pdus; /* number of MT PDUs since start. */
unsigned long mo_pdus; /* number of MO PDUs since start. */
unsigned long mt_errors; /* number of MT errors since start */
unsigned long mo_errors; /* number of MO errors since start */
time_t last_pdu; /* time of last PDU */
time_t start_time; /* when was this connection started */
int use_count; /* use counter. */
time_t delete_after; /* used to control deletion of object -- not ver clean, but... */
} MmscGrp;
@ -131,16 +139,16 @@ extern void *rfs_data;
extern Octstr *rfs_settings;
extern int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func);
extern int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func);
extern void mmsbox_settings_cleanup(void);
extern MmscGrp *get_handler_mmc(Octstr *id, Octstr *to, Octstr *from);
extern void return_mmsc_conn(MmscGrp *m);
extern Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
Octstr **mmc_id);
extern void mmsbox_cleanup_settings(void);
void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func);
void mmsbox_stop_mmsc_conn(Octstr *mmc);
MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func,
List *errors, List *warnings);
int mmsbox_stop_mmsc_conn(Octstr *mmc);
void mmsbox_stop_all_mmsc_conn(void);
typedef struct MmsBoxHTTPClientInfo {
HTTPClient *client;