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
00028
00029
00030
00031
00032
00033
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 "../../mi/mi.h"
00057 #include "../../ip_addr.h"
00058 #include "mi_datagram.h"
00059 #include "datagram_fnc.h"
00060 #include "mi_datagram_parser.h"
00061 #include "mi_datagram_writer.h"
00062
00063
00064
00065
00066 #if !defined(AF_LOCAL)
00067 #define AF_LOCAL AF_UNIX
00068 #endif
00069 #if !defined(PF_LOCAL)
00070 #define PF_LOCAL PF_UNIX
00071 #endif
00072
00073
00074 #define MAX_CTIME_LEN 128
00075 #define MAX_NB_PORT 65535
00076
00077 static int mi_mod_init(void);
00078 static int mi_child_init(int rank);
00079 static int mi_destroy(void);
00080 static int pre_datagram_process(void);
00081 static int post_datagram_process(void);
00082 static void datagram_process(int rank);
00083
00084
00085 static int mi_socket_domain = AF_LOCAL;
00086 static sockaddr_dtgram mi_dtgram_addr;
00087
00088
00089 static char *mi_socket = 0;
00090 int mi_socket_timeout = 2000;
00091 static rx_tx_sockets sockets;
00092
00093
00094 static int mi_unix_socket_uid = -1;
00095 static char *mi_unix_socket_uid_s = 0;
00096 static int mi_unix_socket_gid = -1;
00097 static char *mi_unix_socket_gid_s = 0;
00098 static int mi_unix_socket_mode = S_IRUSR| S_IWUSR| S_IRGRP| S_IWGRP;
00099
00100
00101 static char *mi_reply_indent = DEFAULT_MI_REPLY_IDENT;
00102
00103
00104
00105 MODULE_VERSION
00106
00107
00108 static proc_export_t mi_procs[] = {
00109 {"MI Datagram", pre_datagram_process, post_datagram_process,
00110 datagram_process, MI_CHILD_NO },
00111 {0,0,0,0,0}
00112 };
00113
00114
00115 static param_export_t mi_params[] = {
00116 {"children_count", INT_PARAM, &mi_procs[0].no },
00117 {"socket_name", STR_PARAM, &mi_socket },
00118 {"socket_timeout", INT_PARAM, &mi_socket_timeout },
00119 {"unix_socket_mode", INT_PARAM, &mi_unix_socket_mode },
00120 {"unix_socket_group", STR_PARAM, &mi_unix_socket_gid_s },
00121 {"unix_socket_group", INT_PARAM, &mi_unix_socket_gid },
00122 {"unix_socket_user", STR_PARAM, &mi_unix_socket_uid_s },
00123 {"unix_socket_user", INT_PARAM, &mi_unix_socket_uid },
00124 {"reply_indent", STR_PARAM, &mi_reply_indent },
00125 {0,0,0}
00126 };
00127
00128
00129 struct module_exports exports = {
00130 "mi_datagram",
00131 DEFAULT_DLFLAGS,
00132 0,
00133 mi_params,
00134 0,
00135 0,
00136 0,
00137 mi_procs,
00138 mi_mod_init,
00139 0,
00140 (destroy_function) mi_destroy,
00141 mi_child_init
00142 };
00143
00144
00145 static int mi_mod_init(void)
00146 {
00147 unsigned int port_no;
00148 int n;
00149 struct stat filestat;
00150 struct hostent * host;
00151 char *p, *host_s;
00152 str port_str;
00153
00154
00155 LM_DBG("testing socket existance...\n");
00156
00157 if( mi_socket==NULL || *mi_socket == 0) {
00158 LM_ERR("no DATAGRAM_ socket configured\n");
00159 return -1;
00160 }
00161
00162 LM_DBG("the socket's name/addres is %s\n", mi_socket);
00163
00164 memset( &mi_dtgram_addr, 0, sizeof(mi_dtgram_addr) );
00165
00166 if(strncmp(mi_socket, "udp:",4) == 0)
00167 {
00168
00169 LM_DBG("we have an udp socket\n");
00170
00171 p = mi_socket+4;
00172 if( (*(p)) == '\0') {
00173 LM_ERR("malformed ip address\n");
00174 return -1;
00175 }
00176 host_s=p;
00177 LM_DBG("the remaining address after separating the protocol is %s\n",p);
00178
00179 if( (p = strrchr(p+1, ':')) == 0 ) {
00180 LM_ERR("no port specified\n");
00181 return -1;
00182 }
00183
00184
00185 *p = '\0';
00186 p++;
00187 port_str.s = p;
00188 port_str.len = strlen(p);
00189 LM_DBG("the port string is %s\n", p);
00190 if(str2int(&port_str, &port_no) != 0 ) {
00191 LM_ERR("there is not a valid number port\n");
00192 return -1;
00193 }
00194 *p = '\0';
00195 if (port_no<1024 || port_no>MAX_NB_PORT)
00196 {
00197 LM_ERR("invalid port number; must be in [1024,%d]\n",MAX_NB_PORT);
00198 return -1;
00199 }
00200
00201 if(! (host = resolvehost(host_s, 0)) ) {
00202 LM_ERR("failed to resolve %s\n", host_s);
00203 return -1;
00204 }
00205 LM_DBG("the ip is %s\n",host_s);
00206 if(hostent2su( &(mi_dtgram_addr.udp_addr), host, 0, port_no ) !=0){
00207 LM_ERR("failed to resolve %s\n", mi_socket);
00208 return -1;
00209 }
00210 mi_socket_domain = host->h_addrtype;
00211 return 0;
00212 }
00213
00214 LM_DBG("we have an UNIX socket\n");
00215
00216 n=stat(mi_socket, &filestat);
00217 if( n==0) {
00218 LM_INFO("the socket %s already exists, trying to delete it...\n", mi_socket);
00219 if (unlink(mi_socket)<0) {
00220 LM_ERR("cannot delete old socket: %s\n", strerror(errno));
00221 return -1;
00222 }
00223 } else if (n<0 && errno!=ENOENT) {
00224 LM_ERR("socket stat failed:%s\n", strerror(errno));
00225 return -1;
00226 }
00227
00228
00229 if(!mi_unix_socket_mode) {
00230 LM_WARN("cannot specify mi_unix_socket_mode = 0, forcing it to rw-------\n");
00231 mi_unix_socket_mode = S_IRUSR| S_IWUSR;
00232 }
00233
00234 if (mi_unix_socket_uid_s) {
00235 if (user2uid(&mi_unix_socket_uid, &mi_unix_socket_gid, mi_unix_socket_uid_s)<0) {
00236 LM_ERR("bad user name %s\n", mi_unix_socket_uid_s);
00237 return -1;
00238 }
00239 }
00240
00241 if (mi_unix_socket_gid_s) {
00242 if (group2gid(&mi_unix_socket_gid, mi_unix_socket_gid_s)<0) {
00243 LM_ERR("bad group name %s\n", mi_unix_socket_gid_s);
00244 return -1;
00245 }
00246 }
00247
00248
00249 mi_dtgram_addr.unix_addr.sun_family = AF_LOCAL;
00250 memcpy( mi_dtgram_addr.unix_addr.sun_path, mi_socket, strlen(mi_socket));
00251
00252 return 0;
00253 }
00254
00255
00256 static int mi_child_init(int rank)
00257 {
00258 if (rank==PROC_TIMER || rank>0 ) {
00259 if(mi_datagram_writer_init( DATAGRAM_SOCK_BUF_SIZE , mi_reply_indent )!= 0) {
00260 LM_CRIT("failed to initiate mi_datagram_writer\n");
00261 return -1;
00262 }
00263 }
00264 return 0;
00265 }
00266
00267
00268 static int pre_datagram_process(void)
00269 {
00270 int res;
00271
00272
00273 res = mi_init_datagram_server(&mi_dtgram_addr, mi_socket_domain, &sockets,
00274 mi_unix_socket_mode, mi_unix_socket_uid, mi_unix_socket_gid);
00275
00276 if ( res ) {
00277 LM_CRIT("function mi_init_datagram_server returned with error!!!\n");
00278 return -1;
00279 }
00280
00281 return 0;
00282 }
00283
00284
00285 static void datagram_process(int rank)
00286 {
00287 LM_INFO("a new child %d/%d\n", rank, getpid());
00288
00289
00290 if ( init_mi_child()!=0) {
00291 LM_CRIT("failed to init the mi process\n");
00292 exit(-1);
00293 }
00294 if (mi_init_datagram_buffer()!=0) {
00295 LM_ERR("failed to allocate datagram buffer\n");
00296 exit(-1);
00297 }
00298
00299 if (mi_datagram_writer_init( DATAGRAM_SOCK_BUF_SIZE , mi_reply_indent )!= 0) {
00300 LM_CRIT("failed to initiate mi_datagram_writer\n");
00301 exit(-1);
00302 }
00303
00304 mi_datagram_server(sockets.rx_sock, sockets.tx_sock);
00305
00306 exit(-1);
00307 }
00308
00309
00310 static int post_datagram_process(void)
00311 {
00312
00313 close(sockets.rx_sock);
00314 close(sockets.tx_sock);
00315 return 0;
00316 }
00317
00318
00319 static int mi_destroy(void)
00320 {
00321 int n;
00322 struct stat filestat;
00323
00324
00325 if(mi_socket_domain == AF_UNIX) {
00326 n=stat(mi_socket, &filestat);
00327 if (n==0) {
00328 if (unlink(mi_socket)<0){
00329 LM_ERR("cannot delete the socket (%s): %s\n",
00330 mi_socket, strerror(errno));
00331 goto error;
00332 }
00333 } else if (n<0 && errno!=ENOENT) {
00334 LM_ERR("socket stat failed: %s\n", strerror(errno));
00335 goto error;
00336 }
00337 }
00338
00339 return 0;
00340 error:
00341 return -1;
00342
00343 }