modules_s/domain/domain_mod.c
67cbb9ab
 /*
  * $Id$
09befa54
  *
  * Domain module
  *
  * Copyright (C) 2002-2003 Juha Heinanen
  *
  * This file is part of ser, a free SIP server.
  *
  * ser 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
  *
  * For a license to use the ser software under conditions
  * other than those described here, or to purchase support for this
  * software, please contact iptel.org by e-mail at the following addresses:
  *    info@iptel.org
  *
  * ser 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
d69aa8d7
  *
  * History:
  * -------
  * 2003-03-11: New module interface (janakj)
c6c9f233
  * 2003-03-16: flags export parameter added (janakj)
34dbe688
  * 2003-04-05: default_uri #define used (jiri)
d8fe42f0
  * 2003-04-06: db connection closed in mod_init (janakj)
f56a6186
  * 2004-06-06  updated to the new DB api, cleanup: static dbf & handler,
  *              calls to domain_db_{bind,init,close,ver} (andrei)
09befa54
  */
 
 
 #include "domain_mod.h"
 #include <stdio.h>
79bdcee0
 #include "../../mem/shm_mem.h"
09befa54
 #include "../../sr_module.h"
 #include "domain.h"
caa40974
 #include "fifo.h"
6f23eaf5
 #include "unixsock.h"
09befa54
 
 /*
  * Module management function prototypes
  */
 static int mod_init(void);
 static void destroy(void);
 static int child_init(int rank);
 
ffc62e55
 MODULE_VERSION
caa40974
 
1f45aade
 /*
  * Version of domain table required by the module,
  * increment this value if you change the table in
  * an backwards incompatible way
  */
 #define TABLE_VERSION 1
 
 #define DOMAIN_TABLE "domain"
 #define DOMAIN_TABLE_LEN (sizeof(DOMAIN_TABLE) - 1)
 
 #define DOMAIN_COL "domain"
 #define DOMAIN_COL_LEN (sizeof(DOMAIN_COL) - 1)
 
09befa54
 /*
  * Module parameter variables
  */
f56a6186
 static str db_url = {DEFAULT_RODB_URL, DEFAULT_RODB_URL_LEN};
104b4818
 int db_mode = 0;			/* Database usage mode: 0 = no cache, 1 = cache */
1f45aade
 str domain_table = {DOMAIN_TABLE, DOMAIN_TABLE_LEN};     /* Name of domain table */
 str domain_col = {DOMAIN_COL, DOMAIN_COL_LEN};           /* Name of domain column */
09befa54
 
 /*
  * Other module variables
  */
104b4818
 struct domain_list ***hash_table;	/* Pointer to current hash table pointer */
 struct domain_list **hash_table_1;	/* Pointer to hash table 1 */
 struct domain_list **hash_table_2;	/* Pointer to hash table 2 */
09befa54
 
d69aa8d7
 
 /*
  * Exported functions
  */
 static cmd_export_t cmds[] = {
c6c9f233
 	{"is_from_local",     is_from_local,     0, 0, REQUEST_ROUTE},
 	{"is_uri_host_local", is_uri_host_local, 0, 0, REQUEST_ROUTE},
 	{0, 0, 0, 0, 0}
d69aa8d7
 };
 
 
 /*
  * Exported parameters
  */
 static param_export_t params[] = {
1f45aade
 	{"db_url",		STR_PARAM, &db_url.s	  },
 	{"db_mode",             INT_PARAM, &db_mode       },
 	{"domain_table",        STR_PARAM, &domain_table.s},
 	{"domain_col",          STR_PARAM, &domain_col.s  },
d69aa8d7
 	{0, 0, 0}
 };
 
 
caa40974
 /*
  * Module interface
  */
09befa54
 struct module_exports exports = {
 	"domain", 
d69aa8d7
 	cmds,      /* Exported functions */
 	params,    /* Exported parameters */
09befa54
 	mod_init,  /* module initialization function */
d69aa8d7
 	0,         /* response function*/
09befa54
 	destroy,   /* destroy function */
d69aa8d7
 	0,         /* cancel function */
09befa54
 	child_init /* per-child init function */
 };
 
 
 static int mod_init(void)
 {
1f45aade
 	int i, ver;
caa40974
 
d8fe42f0
 	DBG("domain - initializing\n");
09befa54
 	
1f45aade
 	db_url.len = strlen(db_url.s);
 	domain_table.len = strlen(domain_table.s);
 	domain_col.len = strlen(domain_col.s);
 
79bdcee0
 	/* Check if database module has been loaded */
f56a6186
 	if (domain_db_bind(db_url.s)<0)  return -1;
09befa54
 
caa40974
 	/* Check if cache needs to be loaded from domain table */
 	if (db_mode == 1) {
f56a6186
 		if (domain_db_init(db_url.s)<0) return -1;
1f45aade
 		     /* Check table version */
f56a6186
 		ver = domain_db_ver(&domain_table);
1f45aade
 		if (ver < 0) {
f56a6186
 			LOG(L_ERR, "ERROR: domain:mod_init(): "
 					"error while querying table version\n");
 			domain_db_close();
1f45aade
 			return -1;
 		} else if (ver < TABLE_VERSION) {
f56a6186
 			LOG(L_ERR, "ERROR: domain:mod_init(): invalid table"
 					" version (use ser_mysql.sh reinstall)\n");
 			domain_db_close();
1f45aade
 			return -1;
 		}		
 
caa40974
 		/* Initialize fifo interface */
 		(void)init_domain_fifo();
 
6f23eaf5
 		if (init_domain_unixsock() < 0) {
f56a6186
 			LOG(L_ERR, "ERROR: domain:mod_init(): error while initializing"
 					" unix socket interface\n");
 			domain_db_close();
6f23eaf5
 			return -1;
 		}
 
caa40974
 		/* Initializing hash tables and hash table variable */
79bdcee0
 		hash_table_1 = (struct domain_list **)shm_malloc(sizeof(struct domain_list *) * HASH_SIZE);
 		if (hash_table_1 == 0) {
f56a6186
 			LOG(L_ERR, "ERROR: domain: mod_init(): "
 					"No memory for hash table\n");
79bdcee0
 		}
 
 		hash_table_2 = (struct domain_list **)shm_malloc(sizeof(struct domain_list *) * HASH_SIZE);
 		if (hash_table_2 == 0) {
f56a6186
 			LOG(L_ERR, "ERROR: domain: mod_init():"
 					" No memory for hash table\n");
79bdcee0
 		}
caa40974
 		for (i = 0; i < HASH_SIZE; i++) {
 			hash_table_1[i] = hash_table_2[i] = (struct domain_list *)0;
 		}
79bdcee0
 
 		hash_table = (struct domain_list ***)shm_malloc(sizeof(struct domain_list *));
 		*hash_table = hash_table_1;
 
caa40974
 		if (reload_domain_table() == -1) {
f56a6186
 			LOG(L_CRIT, "ERROR: domain:mod_init():"
 					" Domain table reload failed\n");
caa40974
 			return -1;
 		}
d8fe42f0
 			
f56a6186
 		domain_db_close();
caa40974
 	}
 
09befa54
 	return 0;
 }
 
 
 static int child_init(int rank)
 {
caa40974
 	/* Check if database is needed by child */
27cdb59d
 	if (((db_mode == 0) && (rank > 0)) || ((db_mode == 1) && (rank == PROC_FIFO))) {
f56a6186
 		if (domain_db_init(db_url.s)<0) {
 			LOG(L_ERR, "ERROR: domain:child_init():"
 					" Unable to connect to the database\n");
caa40974
 			return -1;
 		}
09befa54
 	}
 	return 0;
 }
 
 
 static void destroy(void)
 {
cf16adae
 	/* Destroy is called from the main process only,
 	 * there is no need to close database here because
 	 * it is closed in mod_init already
0fe4cd9d
 	 */
09befa54
 }