00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <sys/stat.h>
00037 #include <sys/types.h>
00038 #include <unistd.h>
00039 #include <errno.h>
00040 #include <signal.h>
00041 #include <sys/socket.h>
00042 #include <netinet/in.h>
00043 #include <arpa/inet.h>
00044 #include <stdarg.h>
00045 #include <time.h>
00046 #include <stdio.h>
00047 #include <fcntl.h>
00048
00049
00050 #include "../../sr_module.h"
00051 #include "../../resolve.h"
00052 #include "../../dprint.h"
00053 #include "../../ut.h"
00054 #include "../../mem/mem.h"
00055 #include "../../mem/shm_mem.h"
00056 #include "../../lib/kmi/mi.h"
00057 #include "../../ip_addr.h"
00058 #include "../../pt.h"
00059 #include "../../globals.h"
00060 #include "../../cfg/cfg_struct.h"
00061 #include "mi_datagram.h"
00062 #include "datagram_fnc.h"
00063 #include "mi_datagram_parser.h"
00064 #include "mi_datagram_writer.h"
00065
00066
00067
00068
00069 #if !defined(AF_LOCAL)
00070 #define AF_LOCAL AF_UNIX
00071 #endif
00072 #if !defined(PF_LOCAL)
00073 #define PF_LOCAL PF_UNIX
00074 #endif
00075
00076
00077 #define MAX_CTIME_LEN 128
00078 #define MAX_NB_PORT 65535
00079
00080 static int mi_mod_init(void);
00081 static int mi_child_init(int rank);
00082 static int mi_destroy(void);
00083 static int pre_datagram_process(void);
00084 static int post_datagram_process(void);
00085 static void datagram_process(int rank);
00086
00087
00088 static int mi_socket_domain = AF_LOCAL;
00089 static sockaddr_dtgram mi_dtgram_addr;
00090
00091
00092 static char *mi_socket = 0;
00093 int mi_socket_timeout = 2000;
00094 static rx_tx_sockets sockets;
00095
00096
00097 static int mi_unix_socket_uid = -1;
00098 static char *mi_unix_socket_uid_s = 0;
00099 static int mi_unix_socket_gid = -1;
00100 static char *mi_unix_socket_gid_s = 0;
00101 static int mi_unix_socket_mode = S_IRUSR| S_IWUSR| S_IRGRP| S_IWGRP;
00102
00103
00104 static char *mi_reply_indent = DEFAULT_MI_REPLY_IDENT;
00105
00106
00107
00108 MODULE_VERSION
00109
00110
00111 static proc_export_t mi_procs[] = {
00112 {"MI Datagram", pre_datagram_process, post_datagram_process,
00113 datagram_process, MI_CHILD_NO },
00114 {0,0,0,0,0}
00115 };
00116
00117
00118 static param_export_t mi_params[] = {
00119 {"children_count", INT_PARAM, &mi_procs[0].no },
00120 {"socket_name", STR_PARAM, &mi_socket },
00121 {"socket_timeout", INT_PARAM, &mi_socket_timeout },
00122 {"unix_socket_mode", INT_PARAM, &mi_unix_socket_mode },
00123 {"unix_socket_group", STR_PARAM, &mi_unix_socket_gid_s },
00124 {"unix_socket_group", INT_PARAM, &mi_unix_socket_gid },
00125 {"unix_socket_user", STR_PARAM, &mi_unix_socket_uid_s },
00126 {"unix_socket_user", INT_PARAM, &mi_unix_socket_uid },
00127 {"reply_indent", STR_PARAM, &mi_reply_indent },
00128 {0,0,0}
00129 };
00130
00131
00132 struct module_exports exports = {
00133 "mi_datagram",
00134 DEFAULT_DLFLAGS,
00135 0,
00136 mi_params,
00137 0,
00138 0,
00139 0,
00140 mi_procs,
00141 mi_mod_init,
00142 0,
00143 (destroy_function) mi_destroy,
00144 mi_child_init
00145 };
00146
00147
00148 static int mi_mod_init(void)
00149 {
00150 unsigned int port_no;
00151 int n;
00152 struct stat filestat;
00153 struct hostent * host;
00154 char *p, *host_s;
00155 str port_str;
00156
00157
00158 LM_DBG("testing socket existance...\n");
00159
00160 if( mi_socket==NULL || *mi_socket == 0) {
00161 LM_ERR("no DATAGRAM_ socket configured\n");
00162 return -1;
00163 }
00164
00165 LM_DBG("the socket's name/addres is %s\n", mi_socket);
00166
00167 memset( &mi_dtgram_addr, 0, sizeof(mi_dtgram_addr) );
00168
00169 if(strncmp(mi_socket, "udp:",4) == 0)
00170 {
00171
00172 LM_DBG("we have an udp socket\n");
00173
00174 p = mi_socket+4;
00175 if( (*(p)) == '\0') {
00176 LM_ERR("malformed ip address\n");
00177 return -1;
00178 }
00179 host_s=p;
00180 LM_DBG("the remaining address after separating the protocol is %s\n",p);
00181
00182 if( (p = strrchr(p+1, ':')) == 0 ) {
00183 LM_ERR("no port specified\n");
00184 return -1;
00185 }
00186
00187
00188 *p = '\0';
00189 p++;
00190 port_str.s = p;
00191 port_str.len = strlen(p);
00192 LM_DBG("the port string is %s\n", p);
00193 if(str2int(&port_str, &port_no) != 0 ) {
00194 LM_ERR("there is not a valid number port\n");
00195 return -1;
00196 }
00197 *p = '\0';
00198 if (port_no<1024 || port_no>MAX_NB_PORT)
00199 {
00200 LM_ERR("invalid port number; must be in [1024,%d]\n",MAX_NB_PORT);
00201 return -1;
00202 }
00203
00204 if(! (host = resolvehost(host_s)) ) {
00205 LM_ERR("failed to resolve %s\n", host_s);
00206 return -1;
00207 }
00208 LM_DBG("the ip is %s\n",host_s);
00209 if(hostent2su( &(mi_dtgram_addr.udp_addr), host, 0, port_no ) !=0){
00210 LM_ERR("failed to resolve %s\n", mi_socket);
00211 return -1;
00212 }
00213 mi_socket_domain = host->h_addrtype;
00214 goto done;
00215 }
00216
00217 LM_DBG("we have an UNIX socket\n");
00218
00219 n=stat(mi_socket, &filestat);
00220 if( n==0) {
00221 LM_INFO("the socket %s already exists, trying to delete it...\n", mi_socket);
00222 if(config_check==0) {
00223 if (unlink(mi_socket)<0) {
00224 LM_ERR("cannot delete old socket: %s\n", strerror(errno));
00225 return -1;
00226 }
00227 }
00228 } else if (n<0 && errno!=ENOENT) {
00229 LM_ERR("socket stat failed:%s\n", strerror(errno));
00230 return -1;
00231 }
00232
00233
00234 if(!mi_unix_socket_mode) {
00235 LM_WARN("cannot specify mi_unix_socket_mode = 0, forcing it to rw-------\n");
00236 mi_unix_socket_mode = S_IRUSR| S_IWUSR;
00237 }
00238
00239 if (mi_unix_socket_uid_s) {
00240 if (user2uid(&mi_unix_socket_uid, &mi_unix_socket_gid, mi_unix_socket_uid_s)<0) {
00241 LM_ERR("bad user name %s\n", mi_unix_socket_uid_s);
00242 return -1;
00243 }
00244 }
00245
00246 if (mi_unix_socket_gid_s) {
00247 if (group2gid(&mi_unix_socket_gid, mi_unix_socket_gid_s)<0) {
00248 LM_ERR("bad group name %s\n", mi_unix_socket_gid_s);
00249 return -1;
00250 }
00251 }
00252
00253
00254 mi_dtgram_addr.unix_addr.sun_family = AF_LOCAL;
00255 memcpy( mi_dtgram_addr.unix_addr.sun_path, mi_socket, strlen(mi_socket));
00256
00257 done:
00258
00259 register_procs(mi_procs[0].no);
00260
00261 cfg_register_child(mi_procs[0].no);
00262
00263 return 0;
00264 }
00265
00266
00267 static int mi_child_init(int rank)
00268 {
00269 int i;
00270 int pid;
00271
00272 if (rank==PROC_TIMER || rank>0 ) {
00273 if(mi_datagram_writer_init( DATAGRAM_SOCK_BUF_SIZE , mi_reply_indent )!= 0) {
00274 LM_CRIT("failed to initiate mi_datagram_writer\n");
00275 return -1;
00276 }
00277 }
00278 if (rank==PROC_MAIN) {
00279 if(pre_datagram_process()!=0)
00280 {
00281 LM_ERR("pre-fork function failed\n");
00282 return -1;
00283 }
00284 for(i=0; i<mi_procs[0].no; i++)
00285 {
00286 pid=fork_process(PROC_NOCHLDINIT, "MI DATAGRAM", 1);
00287 if (pid<0)
00288 return -1;
00289 if(pid==0) {
00290
00291
00292
00293 if (cfg_child_init())
00294 return -1;
00295
00296 datagram_process(i);
00297 return 0;
00298 }
00299 }
00300 if(post_datagram_process()!=0)
00301 {
00302 LM_ERR("post-fork function failed\n");
00303 return -1;
00304 }
00305 }
00306 return 0;
00307 }
00308
00309
00310 static int pre_datagram_process(void)
00311 {
00312 int res;
00313
00314
00315 res = mi_init_datagram_server(&mi_dtgram_addr, mi_socket_domain, &sockets,
00316 mi_unix_socket_mode, mi_unix_socket_uid, mi_unix_socket_gid);
00317
00318 if ( res ) {
00319 LM_CRIT("function mi_init_datagram_server returned with error!!!\n");
00320 return -1;
00321 }
00322
00323 return 0;
00324 }
00325
00326
00327 static void datagram_process(int rank)
00328 {
00329 LM_INFO("a new child %d/%d\n", rank, getpid());
00330
00331
00332 if ( init_mi_child(PROC_NOCHLDINIT, 1)!=0) {
00333 LM_CRIT("failed to init the mi process\n");
00334 exit(-1);
00335 }
00336 if (mi_init_datagram_buffer()!=0) {
00337 LM_ERR("failed to allocate datagram buffer\n");
00338 exit(-1);
00339 }
00340
00341 if (mi_datagram_writer_init( DATAGRAM_SOCK_BUF_SIZE , mi_reply_indent )!= 0) {
00342 LM_CRIT("failed to initiate mi_datagram_writer\n");
00343 exit(-1);
00344 }
00345
00346 mi_datagram_server(sockets.rx_sock, sockets.tx_sock);
00347
00348 exit(-1);
00349 }
00350
00351
00352 static int post_datagram_process(void)
00353 {
00354
00355 close(sockets.rx_sock);
00356 close(sockets.tx_sock);
00357 return 0;
00358 }
00359
00360
00361 static int mi_destroy(void)
00362 {
00363 int n;
00364 struct stat filestat;
00365
00366
00367 if(mi_socket_domain == AF_UNIX) {
00368 n=stat(mi_socket, &filestat);
00369 if (n==0) {
00370 if(config_check==0) {
00371 if (unlink(mi_socket)<0){
00372 LM_ERR("cannot delete the socket (%s): %s\n",
00373 mi_socket, strerror(errno));
00374 goto error;
00375 }
00376 }
00377 } else if (n<0 && errno!=ENOENT) {
00378 LM_ERR("socket stat failed: %s\n", strerror(errno));
00379 goto error;
00380 }
00381 }
00382
00383 return 0;
00384 error:
00385 return -1;
00386
00387 }