diff options
Diffstat (limited to 'dpid/dpid.c')
-rw-r--r-- | dpid/dpid.c | 547 |
1 files changed, 277 insertions, 270 deletions
diff --git a/dpid/dpid.c b/dpid/dpid.c index 97e6414d..d8bfeb96 100644 --- a/dpid/dpid.c +++ b/dpid/dpid.c @@ -12,22 +12,26 @@ 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 + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /*! \file * Main functions to set-up dpi information and to initialise sockets */ #include <errno.h> +#include <stdlib.h> /* for exit */ +#include <fcntl.h> /* for F_SETFD, F_GETFD, FD_CLOEXEC */ + #include <sys/stat.h> #include <sys/wait.h> +#include <sys/socket.h> +#include <netinet/tcp.h> + #include <unistd.h> #include "dpid_common.h" #include "dpid.h" #include "dpi.h" #include "dpi_socket_dir.h" -#include "dpi_service.h" #include "misc_new.h" #include "../dpip/dpip.h" @@ -35,71 +39,18 @@ #define QUEUE 5 volatile sig_atomic_t caught_sigchld = 0; +char *SharedKey = NULL; -/*! Return the basename of a filename - */ -static char *get_basename(char *filename) -{ - char *p; - - if (filename && (p = strrchr(filename, '/'))) { - filename = p + 1; - } - return filename; -} - -/*! Close and remove the sockets in the - * given dpi attribute list +/*! Remove dpid_comm_keys file. + * This avoids that dillo instances connect to a stale port after dpid + * has exited (e.g. after a reboot). */ -void rm_dpi_sockets(struct dp *dpi_attr_list, int numdpis) +void cleanup() { - int i; - - for (i = 0; i < numdpis; i++) { - a_Misc_close_fd(dpi_attr_list[i].socket); - (void) unlink(dpi_attr_list[i].sockpath); - } -} - -/*! Close and remove inactive dpi sockets - * \Return - * Number of active dpis. - */ -int rm_inactive_dpi_sockets(struct dp *dpi_attr_list, int numdpis) -{ - int i, active = 0; - - for (i = 0; i < numdpis; i++) { - if (dpi_attr_list[i].pid == 1) { - a_Misc_close_fd(dpi_attr_list[i].socket); - (void) unlink(dpi_attr_list[i].sockpath); - } else - active++; - } - return (active); -} - -/*! Remove sockets - */ -void cleanup(char *socket_dir) -{ - DIR *dir; - struct dirent *dir_entry = NULL; - char *sockpath; - - dir = opendir(socket_dir); - if (dir == NULL) { - ERRMSG("cleanup", "opendir", errno); - return; - } - while ( (dir_entry = readdir(dir)) != NULL ) { - if (dir_entry->d_name[0] == '.') - continue; - sockpath = dStrconcat(socket_dir, "/", dir_entry->d_name, NULL); - unlink(sockpath); - dFree(sockpath); - } - closedir(dir); + char *fname; + fname = dStrconcat(dGethomedir(), "/", dotDILLO_DPID_COMM_KEYS, NULL); + unlink(fname); + dFree(fname); } /*! Free memory used to describe @@ -115,10 +66,6 @@ void free_dpi_attr(struct dp *dpi_attr) dFree(dpi_attr->path); dpi_attr->path = NULL; } - if (dpi_attr->sockpath != NULL) { - dFree(dpi_attr->sockpath); - dpi_attr->sockpath = NULL; - } } /*! Free memory used by the plugin list @@ -152,53 +99,46 @@ void free_services_list(Dlist *s_list) dList_free(s_list); } -/*! \todo - * Remove terminator and est_terminator unless we really want to clean up - * on abnormal exit. - */ -#if 0 /*! Signal handler for SIGINT, SIGQUIT, and SIGTERM. Calls cleanup */ -void terminator(int sig) +static void terminator(int sig) { - (void) signal(SIGCHLD, SIG_DFL); + (void) sig; /* suppress unused parameter warning */ cleanup(); - (void) signal(sig, SIG_DFL); - (void) raise(sig); _exit(0); } /*! Establish handler for termination signals * and register cleanup with atexit */ -void est_terminator(void) +void est_dpi_terminator() { struct sigaction act; sigset_t block; - (void) sigemptyset(&block); - (void) sigaddset(&block, SIGINT); - (void) sigaddset(&block, SIGQUIT); - (void) sigaddset(&block, SIGTERM); - (void) sigaddset(&block, SIGSEGV); + sigemptyset(&block); + sigaddset(&block, SIGHUP); + sigaddset(&block, SIGINT); + sigaddset(&block, SIGQUIT); + sigaddset(&block, SIGTERM); act.sa_handler = terminator; act.sa_mask = block; act.sa_flags = 0; - if (sigaction(SIGINT, &act, NULL) || + if (sigaction(SIGHUP, &act, NULL) || + sigaction(SIGINT, &act, NULL) || sigaction(SIGQUIT, &act, NULL) || - sigaction(SIGTERM, &act, NULL) || sigaction(SIGSEGV, &act, NULL)) { - ERRMSG("est_terminator", "sigaction", errno); + sigaction(SIGTERM, &act, NULL)) { + ERRMSG("est_dpi_terminator", "sigaction", errno); exit(1); } if (atexit(cleanup) != 0) { - ERRMSG("est_terminator", "atexit", 0); + ERRMSG("est_dpi_terminator", "atexit", 0); MSG_ERR("Hey! atexit failed, how did that happen?\n"); exit(1); } } -#endif /*! Identify a given file * Currently there is only one file type associated with dpis. @@ -216,6 +156,56 @@ enum file_type get_file_type(char *file_name) } } +/*! Get dpi directory path from dpidrc + * \Return + * dpi directory on success, NULL on failure + * \Important + * The dpi_dir definition in dpidrc must have no leading white space. + */ +char *get_dpi_dir(char *dpidrc) +{ + FILE *In; + int len; + char *rcline = NULL, *value = NULL, *p; + + if ((In = fopen(dpidrc, "r")) == NULL) { + ERRMSG("dpi_dir", "fopen", errno); + MSG_ERR(" - %s\n", dpidrc); + return (NULL); + } + + while ((rcline = dGetline(In)) != NULL) { + if (strncmp(rcline, "dpi_dir", 7) == 0) + break; + dFree(rcline); + } + fclose(In); + + if (!rcline) { + ERRMSG("dpi_dir", "Failed to find a dpi_dir entry in dpidrc", 0); + MSG_ERR("Put your dillo plugins path in %s\n", dpidrc); + MSG_ERR("e.g. dpi_dir=/usr/local/lib/dillo/dpi\n"); + MSG_ERR("with no leading spaces.\n"); + value = NULL; + } else { + len = (int) strlen(rcline); + if (len && rcline[len - 1] == '\n') + rcline[len - 1] = 0; + + if ((p = strchr(rcline, '='))) { + while (*++p == ' '); + value = dStrdup(p); + } else { + ERRMSG("dpi_dir", "strchr", 0); + MSG_ERR(" - '=' not found in %s\n", rcline); + value = NULL; + } + } + + dFree(rcline); + return (value); +} + /*! Scans a service directory in dpi_dir and fills dpi_attr * \Note * Caller must allocate memory for dpi_attr. @@ -231,7 +221,7 @@ int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr) char *service_dir = NULL; struct stat statinfo; enum file_type ftype; - int retval = -1; + int ret = -1; DIR *dir_stream; struct dirent *dir_entry = NULL; @@ -255,13 +245,13 @@ int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr) dpi_attr->path = dStrconcat(service_dir, "/", dir_entry->d_name, NULL); dpi_attr->id = dStrdup(service); - dpi_attr->sockpath = NULL; + dpi_attr->port = 0; dpi_attr->pid = 1; if (strstr(dpi_attr->path, ".filter") != NULL) dpi_attr->filter = 1; else dpi_attr->filter = 0; - retval = 0; + ret = 0; break; default: break; @@ -269,12 +259,12 @@ int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr) } closedir(dir_stream); - if (retval != 0) + if (ret != 0) MSG_ERR("get_dpi_attr: No dpi plug-in in %s/%s\n", dpi_dir, service); } dFree(service_dir); - return retval; + return ret; } /*! Register a service @@ -289,7 +279,7 @@ int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr) int register_service(struct dp *dpi_attr, char *service) { char *user_dpi_dir, *dpidrc, *user_service_dir, *dir = NULL; - int retval = -1; + int ret = -1; user_dpi_dir = dStrconcat(dGethomedir(), "/", dotDILLO_DPI, NULL); user_service_dir = @@ -313,12 +303,12 @@ int register_service(struct dp *dpi_attr, char *service) /* Check home dir for dpis */ if (access(user_service_dir, F_OK) == 0) { get_dpi_attr(user_dpi_dir, service, dpi_attr); - retval = 0; + ret = 0; } else { /* Check system wide dpis */ if ((dir = get_dpi_dir(dpidrc)) != NULL) { if (access(dir, F_OK) == 0) { get_dpi_attr(dir, service, dpi_attr); - retval = 0; + ret = 0; } else { ERRMSG("register_service", "get_dpi_attr failed", 0); } @@ -330,7 +320,7 @@ int register_service(struct dp *dpi_attr, char *service) dFree(user_service_dir); dFree(dpidrc); dFree(dir); - return (retval); + return ret; } /*! @@ -424,19 +414,18 @@ static int services_alpha_comp(const struct service *s1, return -strcmp(s1->name, s2->name); } -/*! Add services reading a dpidrc file - * each non empty or commented line has the form - * service = path_relative_to_dpidir - * \Return: - * \li Returns number of available services on success - * \li -1 on failure - */ +/*! Add services reading a dpidrc file + * each non empty or commented line has the form + * service = path_relative_to_dpidir + * \Return: + * \li Returns number of available services on success + * \li -1 on failure + */ int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list) { FILE *dpidrc_stream; - char *p, *line = NULL; - char *service, *path; - int i; + char *p, *line = NULL, *service, *path; + int i, st; struct service *s; char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL; @@ -479,16 +468,18 @@ int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list) *services_list = dList_new(8); /* dpidrc parser loop */ - while ((line = dGetline(dpidrc_stream)) != NULL) { - - if (dParser_get_rc_pair(&line, &service, &path) == -1) { - if (line[0] && line[0] != '#' && (!service || !path)) { - MSG_ERR("Syntax error in %s: service=\"%s\" path=\"%s\"\n", - dpidrc, service, path); - } + for (;(line = dGetline(dpidrc_stream)) != NULL; dFree(line)) { + st = dParser_parse_rc_line(&line, &service, &path); + if (st < 0) { + MSG_ERR("dpid: Syntax error in %s: service=\"%s\" path=\"%s\"\n", + dpidrc, service, path); + continue; + } else if (st != 0) { continue; } + _MSG("dpid: service=%s, path=%s\n", service, path); + /* ignore dpi_dir silently */ if (strcmp(service, "dpi_dir") == 0) continue; @@ -507,9 +498,8 @@ int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list) /* if the dpi exist bind service and dpi */ if (i < numdpis) s->dp_index = i; - dFree(line); } - fclose(dpidrc_stream); + fclose(dpidrc_stream); dList_sort(*services_list, (dCompareFunc)services_alpha_comp); @@ -520,127 +510,142 @@ int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list) return (dList_length(*services_list)); } -/*! Initialise the service request socket - * \Return: - * \li Number of sockets (1 == success) - * \li -1 on failure +/* + * Return a socket file descriptor + * (useful to set socket options in a uniform way) */ -int init_srs_socket(char *sockdir) +static int make_socket_fd() { - int retval = -1; - struct sockaddr_un srs_sa; - size_t sun_path_len; - socklen_t addr_sz; + int ret, one = 1; - srs_name = dStrconcat(sockdir, "/", SRS_NAME, NULL); - FD_ZERO(&sock_set); - - /* Initialise srs, service request socket on startup */ - if ((srs = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { - ERRMSG("init_srs_socket", "socket", errno); - return (retval); /* avoids nesting ifs too deeply */ + if ((ret = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + ERRMSG("make_socket_fd", "socket", errno); + } else { + /* avoid delays when sending small pieces of data */ + setsockopt(ret, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); } - /* Set srs to close on exec */ - fcntl(srs, F_SETFD, FD_CLOEXEC | fcntl(srs, F_GETFD)); - srs_sa.sun_family = AF_LOCAL; + /* set some buffering to increase the transfer's speed */ + //setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, + // &sock_buflen, (socklen_t)sizeof(sock_buflen)); + + return ret; +} - sun_path_len = sizeof(srs_sa.sun_path); - if (strlen(srs_name) > sun_path_len) { - ERRMSG("init_srs_socket", "srs_name is too long", 0); - MSG_ERR("\n - it should be <= %lu chars", (ulong_t)sun_path_len); - MSG_ERR("\n - srs_name = %s\n", srs_name); - return(retval); +/*! Bind a socket port on localhost. Try to be close to base_port. + * \Return + * \li listening socket file descriptor on success + * \li -1 on failure + */ +int bind_socket_fd(int base_port, int *p_port) +{ + int sock_fd, port; + struct sockaddr_in sin; + int ok = 0, last_port = base_port + 50; + + if ((sock_fd = make_socket_fd()) == -1) { + return (-1); /* avoids nested ifs */ } - strncpy(srs_sa.sun_path, srs_name, sun_path_len); - addr_sz = (socklen_t) D_SUN_LEN(&srs_sa); + /* Set the socket FD to close on exec */ + fcntl(sock_fd, F_SETFD, FD_CLOEXEC | fcntl(sock_fd, F_GETFD)); - if ((bind(srs, (struct sockaddr *) &srs_sa, addr_sz)) == -1) { - if (errno == EADDRINUSE) { - ERRMSG("init_srs_socket", "bind", errno); - MSG_ERR("srs_sa.sun_path = %s\n", srs_sa.sun_path); - dpi_errno = dpid_srs_addrinuse; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + /* Try to bind a port on localhost */ + for (port = base_port; port <= last_port; ++port) { + sin.sin_port = htons(port); + if ((bind(sock_fd, (struct sockaddr *)&sin, sizeof(sin))) == -1) { + if (errno == EADDRINUSE || errno == EADDRNOTAVAIL) + continue; + ERRMSG("bind_socket_fd", "bind", errno); + } else if (listen(sock_fd, QUEUE) == -1) { + ERRMSG("bind_socket_fd", "listen", errno); } else { - ERRMSG("init_srs_socket", "bind", errno); - MSG_ERR("srs_sa.sun_path = %s\n", srs_sa.sun_path); + *p_port = port; + ok = 1; + break; } - } else if (chmod(srs_sa.sun_path, S_IRUSR | S_IWUSR) == -1) { - ERRMSG("init_srs_socket", "chmod", errno); - MSG_ERR("srs_sa.sun_path = %s\n", srs_sa.sun_path); - } else if (listen(srs, QUEUE) == -1) { - ERRMSG("init_srs_socket", "listen", errno); + } + if (port > last_port) { + MSG_ERR("Hey! Can't find an available port from %d to %d\n", + base_port, last_port); + } + + return ok ? sock_fd : -1; +} + +/*! Save the current port and a shared secret in a file so dillo can find it. + * \Return: + * \li -1 on failure + */ +int save_comm_keys(int srs_port) +{ + int fd, ret = -1; + char *fname, port_str[32]; + + fname = dStrconcat(dGethomedir(), "/", dotDILLO_DPID_COMM_KEYS, NULL); + fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + dFree(fname); + if (fd == -1) { + MSG("save_comm_keys: open %s\n", dStrerror(errno)); } else { - retval = 1; + snprintf(port_str, 16, "%d %s\n", srs_port, SharedKey); + if (CKD_WRITE(fd, port_str) != -1 && CKD_CLOSE(fd) != -1) { + ret = 1; + } + } + + return ret; +} + +/*! Initialise the service request socket (IDS) + * \Return: + * \li Number of sockets (1 == success) + * \li -1 on failure + */ +int init_ids_srs_socket() +{ + int srs_port, ret = -1; + + FD_ZERO(&sock_set); + + if ((srs_fd = bind_socket_fd(DPID_BASE_PORT, &srs_port)) != -1) { + /* create the shared secret */ + SharedKey = a_Misc_mksecret(8); + /* save port number and SharedKey */ + if (save_comm_keys(srs_port) != -1) { + FD_SET(srs_fd, &sock_set); + ret = 1; + } } - FD_SET(srs, &sock_set); - return (retval); + return ret; } -/*! Initialise a single dpi socket +/*! Initialize a single dpi socket * \Return * \li 1 on success * \li -1 on failure */ -int init_dpi_socket(struct dp *dpi_attr, char *sockdir) +int init_dpi_socket(struct dp *dpi_attr) { - int caught_error = 0, s; - char *dpi_nm; /* pointer to basename in dpi_attr->path */ - struct sockaddr_un sa; - size_t sp_len; - socklen_t addr_sz; - size_t sock_buflen = 8192; - - sp_len = sizeof(sa.sun_path); - if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { - ERRMSG("init_all_dpi_sockets", "socket", errno); - return (-1); /* avoids nested ifs */ - } - /* Set the socket FD to close on exec */ - fcntl(s, F_SETFD, FD_CLOEXEC | fcntl(s, F_GETFD)); + int s_fd, port, ret = -1; - /* set some buffering to increase the transfer's speed */ - setsockopt(s, SOL_SOCKET, SO_SNDBUF, - &sock_buflen, (socklen_t)sizeof(sock_buflen)); - - dpi_attr->socket = s; - dpi_attr->sa.sun_family = AF_LOCAL; - dpi_nm = get_basename(dpi_attr->path); - - dpi_attr->sockpath = dStrconcat(sockdir, "/", dpi_nm, "-XXXXXX", NULL); - a_Misc_mkfname(dpi_attr->sockpath); - if (strlen(dpi_attr->sockpath) > sp_len) { - ERRMSG("init_all_dpi_sockets", "socket path is too long", 0); - MSG_ERR("\n - it should be <= %lu chars", (ulong_t)sp_len); - MSG_ERR("\n - socket path = %s\n", dpi_attr->sockpath); - return(-1); - } - strncpy(dpi_attr->sa.sun_path, dpi_attr->sockpath, sp_len); - addr_sz = (socklen_t) D_SUN_LEN(&dpi_attr->sa); - - if ((bind(s, (struct sockaddr *) &dpi_attr->sa, addr_sz)) == -1) { - ERRMSG("init_all_dpi_sockets", "bind", errno); - MSG_ERR("%s\n", dpi_attr->sa.sun_path); - caught_error = 1; - } else if (chmod(dpi_attr->sa.sun_path, S_IRUSR | S_IWUSR) == -1) { - ERRMSG("init_all_dpi_sockets", "chmod", errno); - MSG_ERR("%s\n", dpi_attr->sa.sun_path); - caught_error = 1; - } else if (listen(s, QUEUE) == -1) { - ERRMSG("init_all_dpi_sockets", "listen", errno); - caught_error = 1; - } - - if (caught_error) { - return (-1); - } else { - FD_SET(s, &sock_set); - return (1); + if ((s_fd = bind_socket_fd(DPID_BASE_PORT, &port)) != -1) { + dpi_attr->sock_fd = s_fd; + dpi_attr->port = port; + FD_SET(s_fd, &sock_set); + ret = 1; } + + return ret; } /*! Setup sockets for the plugins and add them to - * to the set of sockets (sock_set) watched by select. + * the set of sockets (sock_set) watched by select. * \Return * \li Number of sockets on success * \li -1 on failure @@ -649,17 +654,13 @@ int init_dpi_socket(struct dp *dpi_attr, char *sockdir) * \Uses * numdpis, srs, srs_name */ -int init_all_dpi_sockets(struct dp *dpi_attr_list, char *sockdir) +int init_all_dpi_sockets(struct dp *dpi_attr_list) { int i; - struct sockaddr_un sa; - size_t sp_len; - - sp_len = sizeof(sa.sun_path); /* Initialise sockets for each dpi */ for (i = 0; i < numdpis; i++) { - if (init_dpi_socket(dpi_attr_list + i, sockdir) == -1) + if (init_dpi_socket(dpi_attr_list + i) == -1) return (-1); numsocks++; } @@ -688,7 +689,7 @@ void handle_sigchld(void) for (i = 0; i < numdpis; i++) { if (waitpid(dpi_attr_list[i].pid, &status, WNOHANG) > 0) { dpi_attr_list[i].pid = 1; - FD_SET(dpi_attr_list[i].socket, &sock_set); + FD_SET(dpi_attr_list[i].sock_fd, &sock_set); numsocks++; } } @@ -714,45 +715,62 @@ void est_dpi_sigchld(void) } } +/*! EINTR aware connect() call */ +int ckd_connect (int sock_fd, struct sockaddr *addr, socklen_t len) +{ + ssize_t ret; + + do { + ret = connect(sock_fd, addr, len); + } while (ret == -1 && errno == EINTR); + if (ret == -1) { + ERRMSG("dpid.c", "connect", errno); + } + return ret; +} + /*! Send DpiBye command to all active non-filter dpis */ void stop_active_dpis(struct dp *dpi_attr_list, int numdpis) { - static char *DpiBye_cmd = NULL; - int i, dpi_socket; - struct sockaddr_un dpi_addr; - struct sockaddr_un sa; - size_t sun_path_len, addr_len; + char *bye_cmd, *auth_cmd; + int i, sock_fd; + struct sockaddr_in sin; - if (!DpiBye_cmd) - DpiBye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye"); + bye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye"); + auth_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "auth", SharedKey); - sun_path_len = sizeof(sa.sun_path); - addr_len = sizeof(dpi_addr); - - dpi_addr.sun_family = AF_LOCAL; + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); for (i = 0; i < numdpis; i++) { /* Skip inactive dpis and filters */ if (dpi_attr_list[i].pid == 1 || dpi_attr_list[i].filter) continue; - if ((dpi_socket = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { + if ((sock_fd = make_socket_fd()) == -1) { ERRMSG("stop_active_dpis", "socket", errno); + continue; } - if (strlen(dpi_attr_list[i].sockpath) > sun_path_len) { - ERRMSG("stop_active_dpis", "socket path is too long", 0); - MSG_ERR("\n - it should be <= %lu chars",(ulong_t)sun_path_len); - MSG_ERR("\n - socket path = %s\n", dpi_attr_list[i].sockpath); - } - strncpy(dpi_addr.sun_path, dpi_attr_list[i].sockpath, sun_path_len); - if (connect(dpi_socket, (struct sockaddr *) &dpi_addr, addr_len) == -1) { + + sin.sin_port = htons(dpi_attr_list[i].port); + if (ckd_connect(sock_fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { ERRMSG("stop_active_dpis", "connect", errno); - MSG_ERR("%s\n", dpi_addr.sun_path); + MSG_ERR("%s\n", dpi_attr_list[i].path); + } else if (CKD_WRITE(sock_fd, auth_cmd) == -1) { + ERRMSG("stop_active_dpis", "write", errno); + } else if (CKD_WRITE(sock_fd, bye_cmd) == -1) { + ERRMSG("stop_active_dpis", "write", errno); } - (void) write(dpi_socket, DpiBye_cmd, strlen(DpiBye_cmd)); - a_Misc_close_fd(dpi_socket); + a_Misc_close_fd(sock_fd); } + + dFree(auth_cmd); + dFree(bye_cmd); + + /* Allow child dpis some time to read dpid_comm_keys before erasing it */ + sleep (1); } /*! Removes dpis in dpi_attr_list from the @@ -764,8 +782,8 @@ void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis) int i; for (i = 0; i < numdpis; i++) { - FD_CLR(dpi_attr_list[i].socket, &sock_set); - a_Misc_close_fd(dpi_attr_list[i].socket); + FD_CLR(dpi_attr_list[i].sock_fd, &sock_set); + a_Misc_close_fd(dpi_attr_list[i].sock_fd); } } @@ -776,20 +794,19 @@ void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis) * \Return * Number of available dpis */ -int register_all_cmd(char *sockdir) +int register_all_cmd() { stop_active_dpis(dpi_attr_list, numdpis); - rm_dpi_sockets(dpi_attr_list, numdpis); free_plugin_list(&dpi_attr_list, numdpis); free_services_list(services_list); services_list = NULL; numdpis = 0; numsocks = 1; /* the srs socket */ FD_ZERO(&sock_set); - FD_SET(srs, &sock_set); + FD_SET(srs_fd, &sock_set); numdpis = register_all(&dpi_attr_list); fill_services_list(dpi_attr_list, numdpis, &services_list); - numsocks = init_all_dpi_sockets(dpi_attr_list, sockdir); + numsocks = init_all_dpi_sockets(dpi_attr_list); return (numdpis); } @@ -798,16 +815,16 @@ int register_all_cmd(char *sockdir) * \Return * message on success, NULL on failure */ -char *get_message(int sock, char *dpi_tag) +char *get_message(int sock_fd, char *dpi_tag) { char *msg, *d_cmd; - msg = a_Dpip_get_attr(dpi_tag, strlen(dpi_tag), "msg"); + msg = a_Dpip_get_attr(dpi_tag, "msg"); if (msg == NULL) { ERRMSG("get_message", "failed to parse msg", 0); d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "DpiError", "Failed to parse request"); - (void) CKD_WRITE(sock, d_cmd); + (void) CKD_WRITE(sock_fd, d_cmd); dFree(d_cmd); } return (msg); @@ -832,40 +849,30 @@ int service_match(const struct service *A, const char *B) } /*! - * Send socket path that matches dpi_id to client + * Send socket port that matches dpi_id to client */ -void send_sockpath(int sock, char *dpi_tag, struct dp *dpi_attr_list) +void send_sockport(int sock_fd, char *dpi_tag, struct dp *dpi_attr_list) { int i; - char *dpi_id; - char *d_cmd; + char *dpi_id, *d_cmd, port_str[16]; struct service *serv; - dReturn_if_fail((dpi_id = get_message(sock, dpi_tag)) != NULL); + dReturn_if_fail((dpi_id = get_message(sock_fd, dpi_tag)) != NULL); serv = dList_find_custom(services_list,dpi_id,(dCompareFunc)service_match); if (serv == NULL || (i = serv->dp_index) == -1) for (i = 0; i < numdpis; i++) if (!strncmp(dpi_attr_list[i].id, dpi_id, - dpi_attr_list[i].id - strchr(dpi_attr_list[i].id, '.'))) + dpi_attr_list[i].id - strchr(dpi_attr_list[i].id, '.'))) break; if (i < numdpis) { /* found */ - if (access(dpi_attr_list[i].path, F_OK) == -1) { - ERRMSG("send_sockpath", "access", errno); - MSG_ERR(" - %s\n", dpi_attr_list[i].sockpath); - d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", - "DpiError", "Plugin currently unavailable"); - (void) CKD_WRITE(sock, d_cmd); - dFree(d_cmd); - } else { - d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", - "send_data", dpi_attr_list[i].sockpath); - (void) CKD_WRITE(sock, d_cmd); - dFree(d_cmd); - } + snprintf(port_str, 8, "%d", dpi_attr_list[i].port); + d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "send_data", port_str); + (void) CKD_WRITE(sock_fd, d_cmd); + dFree(d_cmd); } dFree(dpi_id); |