?? jabber.c
字號:
/* * $Id: jabber.c,v 1.6 2006/03/01 10:58:37 bogdan_iancu Exp $ * * XJAB module * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of openser, a free SIP server. * * openser is free software; you can redistribute it and/or modify * 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 * * openser is distributed in the hope that it will be useful, * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * --- * * History * ------- * 2003-02-28 connection management with ihttp implemented (dcm) * 2003-02-24 first version of callback functions for ihttp (dcm) * 2003-02-13 lot of comments enclosed in #ifdef XJ_EXTRA_DEBUG (dcm) * 2003-03-11 New module interface (janakj) * 2003-03-16 flags export parameter added (janakj) * 2003-04-06 rank 0 changed to 1 in child_init (janakj) * 2003-06-19 fixed too many Jabber workers bug (mostly on RH9.0) (dcm) * 2003-08-05 adapted to the new parse_content_type_hdr function (bogdan) * 2004-06-07 db API update (andrei) */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/ipc.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include "../../sr_module.h"#include "../../error.h"#include "../../ut.h"#include "../../mem/shm_mem.h"#include "../../mem/mem.h"#include "../../globals.h"#include "../../timer.h"#include "../../parser/parse_uri.h"#include "../../parser/parse_content.h"#include "../../parser/parse_from.h"#include "../../db/db.h"#include "../tm/tm_load.h"#ifdef HAVE_IHTTP#include "../ihttp/ih_load.h"#endif#include "xjab_load.h"#include "xjab_worker.h"#include "xjab_util.h"MODULE_VERSION/** TM bind */struct tm_binds tmb;#ifdef HAVE_IHTTP/** iHTTP bind */struct ih_binds ihb;/** iHTTP callback functions */int xjab_mod_info(ih_req_p _irp, void *_p, char *_bb, int *_bl, char *_hb, int *_hl);int xjab_connections(ih_req_p _irp, void *_p, char *_bb, int *_bl, char *_hb, int *_hl);#endif/** workers list */xj_wlist jwl = NULL;/** Structure that represents database connection */static db_con_t** db_con;static db_func_t jabber_dbf;/** parameters */static char *db_url = "mysql://root@127.0.0.1/sip_jab";char *db_table = "jusers";char *registrar=NULL; /*"sip:registrar@example.org";*/int nrw = 2;int max_jobs = 10;char *jaddress = "127.0.0.1";int jport = 5222;char *jaliases = NULL;char *jdomain = NULL;char *proxy = NULL;int delay_time = 90;int sleep_time = 20;int cache_time = 600;int check_time = 20;int **pipes = NULL;static int mod_init(void);static int child_init(int rank);int xjab_manage_sipmsg(struct sip_msg *msg, int type);void xjab_check_workers(int mpid);static int xj_send_message(struct sip_msg*, char*, char*);static int xj_join_jconf(struct sip_msg*, char*, char*);static int xj_exit_jconf(struct sip_msg*, char*, char*);static int xj_go_online(struct sip_msg*, char*, char*);static int xj_go_offline(struct sip_msg*, char*, char*);void destroy(void);/* * Exported functions */static cmd_export_t cmds[] = { {"jab_send_message", xj_send_message, 0, 0, REQUEST_ROUTE}, {"jab_join_jconf", xj_join_jconf, 0, 0, REQUEST_ROUTE}, {"jab_exit_jconf", xj_exit_jconf, 0, 0, REQUEST_ROUTE}, {"jab_go_online", xj_go_online, 0, 0, REQUEST_ROUTE}, {"jab_go_offline", xj_go_offline, 0, 0, REQUEST_ROUTE}, {"jab_register_watcher", (cmd_function)xj_register_watcher, XJ_NO_SCRIPT_F, 0, 0 }, {"jab_unregister_watcher", (cmd_function)xj_unregister_watcher, XJ_NO_SCRIPT_F, 0, 0 }, {"load_xjab", (cmd_function)load_xjab, XJ_NO_SCRIPT_F, 0, 0 }, {0, 0, 0, 0, 0}};/* * Exported parameters */static param_export_t params[] = { {"db_url", STR_PARAM, &db_url }, {"jaddress", STR_PARAM, &jaddress }, {"aliases", STR_PARAM, &jaliases }, {"proxy", STR_PARAM, &proxy }, {"jdomain", STR_PARAM, &jdomain }, {"registrar", STR_PARAM, ®istrar }, {"jport", INT_PARAM, &jport }, {"workers", INT_PARAM, &nrw }, {"max_jobs", INT_PARAM, &max_jobs }, {"cache_time", INT_PARAM, &cache_time}, {"delay_time", INT_PARAM, &delay_time}, {"sleep_time", INT_PARAM, &sleep_time}, {"check_time", INT_PARAM, &check_time}, {0, 0, 0}};struct module_exports exports= { "jabber", cmds, /* Exported functions */ params, /* Exported parameters */ 0, /* exported statistics */ mod_init, /* module initialization function */ (response_function) 0, (destroy_function) destroy, child_init /* per-child init function */};/** * init module function */static int mod_init(void){#ifdef HAVE_IHTTP load_ih_f load_ih;#endif int i; DBG("XJAB:mod_init: initializing ...\n"); if(!jdomain) { LOG(L_ERR, "XJAB:mod_init: ERROR jdomain is NULL\n"); return -1; } /* import mysql functions */ if (bind_dbmod(db_url, &jabber_dbf)<0) { LOG(L_ERR, "XJAB:mod_init: error - database module not found\n"); return -1; } if (!DB_CAPABILITY(jabber_dbf, DB_CAP_QUERY)) { LOG(L_ERR, "XJAB:mod_init: Database module does not implement 'query' function\n"); return -1; } db_con = (db_con_t**)shm_malloc(nrw*sizeof(db_con_t*)); if (db_con == NULL) { LOG(L_ERR, "XJAB:mod_init: Error while allocating db_con's\n"); return -1; } /* load the TM API */ if (load_tm_api(&tmb)!=0) { LOG(L_ERR, "ERROR:xjab:mod_init: can't load TM API\n"); return -1; }#ifdef HAVE_IHTTP /* import the iHTTP auto-loading function */ if ( !(load_ih=(load_ih_f)find_export("load_ih", IH_NO_SCRIPT_F, 0))) { LOG(L_ERR, "ERROR:xjab:mod_init: can't import load_ih\n"); return -1; } /* let the auto-loading function load all TM stuff */ if (load_ih( &ihb )==-1) return -1;#endif pipes = (int**)pkg_malloc(nrw*sizeof(int*)); if (pipes == NULL) { LOG(L_ERR, "XJAB:mod_init:Error while allocating pipes\n"); return -1; } for(i=0; i<nrw; i++) { pipes[i] = (int*)pkg_malloc(2*sizeof(int)); if (!pipes[i]) { LOG(L_ERR, "XJAB:mod_init: Error while allocating pipes\n"); return -1; } } for(i=0; i<nrw; i++) { db_con[i] = jabber_dbf.init(db_url); if (!db_con[i]) { LOG(L_ERR, "XJAB:mod_init: Error while connecting database\n"); return -1; } else { if (jabber_dbf.use_table(db_con[i], db_table) < 0) { LOG(L_ERR, "XJAB:mod_init: Error in use_table\n"); return -1; } DBG("XJAB:mod_init: Database connection opened successfully\n"); } } /** creating the pipes */ for(i=0;i<nrw;i++) { /* create the pipe*/ if (pipe(pipes[i])==-1) { LOG(L_ERR, "XJAB:mod_init: error - cannot create pipe!\n"); return -1; } DBG("XJAB:mod_init: pipe[%d] = <%d>-<%d>\n", i, pipes[i][0], pipes[i][1]); } if((jwl = xj_wlist_init(pipes,nrw,max_jobs,cache_time,sleep_time, delay_time)) == NULL) { LOG(L_ERR, "XJAB:mod_init: error initializing workers list\n"); return -1; } if(xj_wlist_set_aliases(jwl, jaliases, jdomain, proxy) < 0) { LOG(L_ERR, "XJAB:mod_init: error setting aliases and outbound proxy\n"); return -1; } DBG("XJAB:mod_init: initialized ...\n"); return 0;}/* * Initialize children */static int child_init(int rank){ int i, j, mpid, cpid; DBG("XJAB:child_init: initializing child <%d>\n", rank); /* Rank 0 is main process now - 1 is the first child (janakj) */ if(rank == 1) {#ifdef HAVE_IHTTP /** register iHTTP callbacks -- go forward in any case*/ ihb.reg_f("xjab", "XMPP Gateway", IH_MENU_YES, xjab_mod_info, NULL); ihb.reg_f("xjabc", "XMPP connections", IH_MENU_YES, xjab_connections, NULL);#endif if((mpid=fork())<0 ) { LOG(L_ERR, "XJAB:child_init:error - cannot launch worker's" " manager\n"); return -1; } if(mpid == 0) { /** launching the workers */ for(i=0;i<nrw;i++) { if ( (cpid=fork())<0 ) { LOG(L_ERR,"XJAB:child_init:error - cannot launch worker\n"); return -1; } if (cpid == 0) { for(j=0;j<nrw;j++) if(j!=i) close(pipes[j][0]); close(pipes[i][1]); if(xj_wlist_set_pid(jwl, getpid(), i) < 0) { LOG(L_ERR, "XJAB:child_init:error setting worker's" " pid\n"); return -1; } xj_worker_process(jwl,jaddress,jport,i,db_con[i], &jabber_dbf); exit(0); } } mpid = getpid(); while(1) { sleep(check_time); xjab_check_workers(mpid); } } } //if(pipes) //{ // for(i=0;i<nrw;i++) // close(pipes[i][0]); //} return 0;}/** * send the SIP MESSAGE through Jabber */static int xj_send_message(struct sip_msg *msg, char* foo1, char * foo2){ DBG("XJAB: processing SIP MESSAGE\n"); return xjab_manage_sipmsg(msg, XJ_SEND_MESSAGE);}/** * join a Jabber conference */static int xj_join_jconf(struct sip_msg *msg, char* foo1, char * foo2){ DBG("XJAB: join a Jabber conference\n"); return xjab_manage_sipmsg(msg, XJ_JOIN_JCONF);}/** * exit from Jabber conference */static int xj_exit_jconf(struct sip_msg *msg, char* foo1, char * foo2){ DBG("XJAB: exit from a Jabber conference\n"); return xjab_manage_sipmsg(msg, XJ_EXIT_JCONF);}/** * go online in Jabber network */static int xj_go_online(struct sip_msg *msg, char* foo1, char * foo2){ DBG("XJAB: go online in Jabber network\n"); return xjab_manage_sipmsg(msg, XJ_GO_ONLINE);}/** * go offline in Jabber network */static int xj_go_offline(struct sip_msg *msg, char* foo1, char * foo2){ DBG("XJAB: go offline in Jabber network\n"); return xjab_manage_sipmsg(msg, XJ_GO_OFFLINE);}/** * manage SIP message */int xjab_manage_sipmsg(struct sip_msg *msg, int type){ str body, dst, from_uri; xj_sipmsg jsmsg; int pipe, fl; t_xj_jkey jkey, *p; int mime; body.len = 0; body.s = 0; // extract message body - after that whole SIP MESSAGE is parsed if (type==XJ_SEND_MESSAGE) { /* get the message's body */ body.s = get_body( msg ); if(body.s==0) { LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR cannot extract body from" " msg\n"); goto error; } /* content-length (if present) must be already parsed */ if(!msg->content_length) { LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR no Content-Length" " header found!\n"); goto error; } body.len = get_content_length(msg); /* parse the content-type header */ if((mime=parse_content_type_hdr(msg))<1) { LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR cannot parse" " Content-Type header\n"); goto error; } /* check the content-type value */ if(mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN && mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM) { LOG(L_ERR,"XJAB:xjab_manage_sipmsg: ERROR invalid content-type for" " a message request! type found=%d\n", mime); goto error; } } // check for TO and FROM headers - if is not SIP MESSAGE if(parse_headers(msg,HDR_TO_F|HDR_FROM_F,0)==-1 || !msg->to || !msg->from) { LOG(L_ERR,"XJAB:xjab_manage_sipmsg: cannot find TO or FROM HEADERS!\n"); goto error; } /* parsing from header */ if ( parse_from_header( msg )<0 || msg->from->parsed==NULL) { DBG("ERROR:xjab_manage_sipmsg: cannot get FROM header\n"); goto error; } from_uri.s = ((struct to_body*)msg->from->parsed)->uri.s; from_uri.len = ((struct to_body*)msg->from->parsed)->uri.len; if(xj_extract_aor(&from_uri, 0)) { DBG("ERROR:xjab_manage_sipmsg: cannot get AoR from FROM header\n"); goto error; } jkey.hash = xj_get_hash(&from_uri, NULL); jkey.id = &from_uri; // get the communication pipe with the worker switch(type) { case XJ_SEND_MESSAGE: case XJ_JOIN_JCONF: case XJ_GO_ONLINE: if((pipe = xj_wlist_get(jwl, &jkey, &p)) < 0) { DBG("XJAB:xjab_manage_sipmsg: cannot find pipe of the worker!\n"); goto error; } break; case XJ_EXIT_JCONF: case XJ_GO_OFFLINE: if((pipe = xj_wlist_check(jwl, &jkey, &p)) < 0) { DBG("XJAB:xjab_manage_sipmsg: no open Jabber session for" " <%.*s>!\n", from_uri.len, from_uri.s); goto error;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -