diff options
-rw-r--r-- | dpid/dpid.c | 348 | ||||
-rw-r--r-- | dpid/dpid.h | 30 | ||||
-rw-r--r-- | dpid/dpid_common.h | 2 | ||||
-rw-r--r-- | dpid/dpidc | 16 | ||||
-rw-r--r-- | dpid/main.c | 64 | ||||
-rw-r--r-- | src/IO/Url.h | 2 | ||||
-rw-r--r-- | src/IO/dpi.c | 298 | ||||
-rw-r--r-- | src/dillo.cc | 2 |
8 files changed, 324 insertions, 438 deletions
diff --git a/dpid/dpid.c b/dpid/dpid.c index 8d325694..70f59a62 100644 --- a/dpid/dpid.c +++ b/dpid/dpid.c @@ -19,11 +19,13 @@ * 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 <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 <unistd.h> #include "dpid_common.h" #include "dpid.h" @@ -37,70 +39,11 @@ volatile sig_atomic_t caught_sigchld = 0; -/*! 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 - */ -void rm_dpi_sockets(struct dp *dpi_attr_list, int numdpis) -{ - 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. +/*! Remove UDS filenames */ -int rm_inactive_dpi_sockets(struct dp *dpi_attr_list, int numdpis) +void cleanup() { - 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); } /*! Free memory used to describe @@ -116,10 +59,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 @@ -306,7 +245,7 @@ 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; @@ -573,127 +512,122 @@ 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) +/*! 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 init_srs_socket(char *sockdir) +int bind_socket_fd(int base_port, int *p_port) { - int retval = -1; - struct sockaddr_un srs_sa; - size_t sun_path_len; - socklen_t addr_sz; + int sock_fd, port; + struct sockaddr_in sin; + //size_t sock_buflen = 8192; + int ok = 0, last_port = base_port + 50; - srs_name = dStrconcat(sockdir, "/", SRS_NAME, NULL); - FD_ZERO(&sock_set); + if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + ERRMSG("bind_socket_fd", "socket", errno); + return (-1); /* avoids nested ifs */ + } + /* Set the socket FD to close on exec */ + fcntl(sock_fd, F_SETFD, FD_CLOEXEC | fcntl(sock_fd, F_GETFD)); - /* 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 */ + /* set some buffering to increase the transfer's speed */ + //setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, + // &sock_buflen, (socklen_t)sizeof(sock_buflen)); + + 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 { + *p_port = port; + ok = 1; + break; + } + } + if (port > last_port) { + MSG_ERR("Hey! Can't find an available port from %d to %d\n", + base_port, last_port); } - /* Set srs to close on exec */ - fcntl(srs, F_SETFD, FD_CLOEXEC | fcntl(srs, F_GETFD)); - srs_sa.sun_family = AF_LOCAL; + return ok ? sock_fd : -1; +} - 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); +/*! Save the current port in a file so dillo can find it. + * \Return: + * \li -1 on failure + */ +int save_comm_keys(int srs_port) +{ + int fd; + char *fname, ret = -1, port_str[16]; + + 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 { + snprintf(port_str, 8, "%d\n", srs_port); + if (CKD_WRITE(fd, port_str) != -1) + ret = 1; } - strncpy(srs_sa.sun_path, srs_name, sun_path_len); - addr_sz = (socklen_t) D_SUN_LEN(&srs_sa); - 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; - } else { - ERRMSG("init_srs_socket", "bind", errno); - MSG_ERR("srs_sa.sun_path = %s\n", srs_sa.sun_path); + 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) { + /* save port number */ + if (save_comm_keys(srs_port) != -1) { + FD_SET(srs_fd, &sock_set); + ret = 1; } - } 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); - } else { - retval = 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 @@ -702,17 +636,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++; } @@ -741,7 +671,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++; } } @@ -772,43 +702,34 @@ void est_dpi_sigchld(void) void stop_active_dpis(struct dp *dpi_attr_list, int numdpis) { static char *DpiBye_cmd = NULL; - int i, dpi_socket, rc; - struct sockaddr_un dpi_addr; - struct sockaddr_un sa; - size_t sun_path_len, addr_len; + int i, sock_fd; + struct sockaddr_in sin; if (!DpiBye_cmd) DpiBye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye"); - sun_path_len = sizeof(sa.sun_path); - - 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 = socket(AF_INET, SOCK_STREAM, 0)) == -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); - addr_len = D_SUN_LEN(&dpi_addr); - if (connect(dpi_socket, (struct sockaddr *) &dpi_addr, addr_len) == -1) { + sin.sin_port = htons(dpi_attr_list[i].port); + if (connect(sock_fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { ERRMSG("stop_active_dpis", "connect", errno); - MSG_ERR("%s\n", dpi_addr.sun_path); - } - rc = write(dpi_socket, DpiBye_cmd, strlen(DpiBye_cmd)); - if (rc == -1) { + MSG_ERR("%s\n", dpi_attr_list[i].path); + } else if (write(sock_fd, DpiBye_cmd, strlen(DpiBye_cmd)) == -1) { MSG("stop_active_dpis: Error on sending BYE command: %s\n", dStrerror(errno)); } - a_Misc_close_fd(dpi_socket); + a_Misc_close_fd(sock_fd); } } @@ -821,8 +742,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); } } @@ -833,20 +754,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); } @@ -855,7 +775,7 @@ 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; @@ -864,7 +784,7 @@ char *get_message(int sock, char *dpi_tag) 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); @@ -889,40 +809,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); diff --git a/dpid/dpid.h b/dpid/dpid.h index 5c5aa3f8..7302356b 100644 --- a/dpid/dpid.h +++ b/dpid/dpid.h @@ -6,9 +6,10 @@ #define DPID_H #include <sys/socket.h> -#include <sys/select.h> /* for fd_set */ +#include <sys/select.h> /* for fd_set */ #include <sys/un.h> -#include <signal.h> /* for sig_atomic_t */ +#include <signal.h> /* for sig_atomic_t */ +#include <netinet/in.h> /* for ntohl, IPPORT_USERRESERVED and stuff */ #include "d_size.h" @@ -16,21 +17,22 @@ #define PATH_LEN 50 #define CMDLEN 20 #define MSGLEN 50 +#define DPID_BASE_PORT (IPPORT_USERRESERVED + 20) + /*! \TODO: Should read this from dillorc */ #define SRS_NAME "dpid.srs" char *srs_name; -/*! dpid service request socket */ -int srs; +/*! dpid's service request socket file descriptor */ +int srs_fd; /*! plugin state information */ struct dp { char *id; char *path; - char *sockpath; - int socket; - struct sockaddr_un sa; + int sock_fd; + int port; pid_t pid; int filter; }; @@ -62,9 +64,7 @@ extern volatile sig_atomic_t caught_sigchld; void rm_dpi_sockets(struct dp *dpi_attr_list, int numdpis); -int rm_inactive_dpi_sockets(struct dp *dpi_attr_list, int numdpis); - -void cleanup(char *socket_dir); +void cleanup(); void free_dpi_attr(struct dp *dpi_attr); @@ -82,11 +82,11 @@ int register_all(struct dp **attlist); int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list); -int init_srs_socket(char *sockdir); +int init_ids_srs_socket(); -int init_dpi_socket(struct dp *dpi_attr, char *sockdir); +int init_dpi_socket(struct dp *dpi_attr); -int init_all_dpi_sockets(struct dp *dpi_attr_list, char *sockdir); +int init_all_dpi_sockets(struct dp *dpi_attr_list); void dpi_sigchld(int sig); @@ -98,12 +98,12 @@ void stop_active_dpis(struct dp *dpi_attr_list, int numdpis); void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis); -int register_all_cmd(char *sockdir); +int register_all_cmd(); char *get_message(int sock, char *dpi_tag); int service_match(const struct service *A, const char *B); -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); #endif diff --git a/dpid/dpid_common.h b/dpid/dpid_common.h index 5a792b04..65b8bc89 100644 --- a/dpid/dpid_common.h +++ b/dpid/dpid_common.h @@ -23,6 +23,8 @@ #define dotDILLO_DPI ".dillo/dpi" #define dotDILLO_DPIDRC ".dillo/dpidrc" +#define dotDILLO_DPID_COMM_KEYS ".dillo/dpid_comm_keys" + #define ERRMSG(CALLER, CALLED, ERR)\ errmsg(CALLER, CALLED, ERR, __FILE__, __LINE__) #define _ERRMSG(CALLER, CALLED, ERR) @@ -7,14 +7,20 @@ # stop: Stops dpid. use strict; -use IO::Socket::UNIX; +use IO::Socket::INET; # Get socket directory name -open(DSD, "<$ENV{HOME}/.dillo/dpi_socket_dir"); -my $dir = <DSD>; +#open(DSD, "<$ENV{HOME}/.dillo/dpi_socket_dir"); +#my $dir = <DSD>; +#close(DSD); + +# Get dpid's listening port from saved file +open(DSD, "<$ENV{HOME}/.dillo/dpid_comm_keys"); +my $port = <DSD>; close(DSD); +print "Got: localhost:$port\n"; -my $socket = IO::Socket::UNIX->new(Peer => "$dir/dpid.srs", Type => SOCK_STREAM, Timeout => 1000 ) or die "new: $@"; +my $socket = IO::Socket::INET->new(Peer => "localhost:$port", Type => SOCK_STREAM, Timeout => 1000 ) or die "new: $@"; $socket->autoflush(1); @@ -23,7 +29,7 @@ my %dpi_command = ( "stop" => "<dpi cmd='DpiBye' '>", ); -if ( exists($dpi_command{$ARGV[0]}) ) { +if ( $#ARGV == 0 && exists($dpi_command{$ARGV[0]}) ) { print $socket $dpi_command{$ARGV[0]}; } else { close($socket); diff --git a/dpid/main.c b/dpid/main.c index 7ecae76a..fcb11cef 100644 --- a/dpid/main.c +++ b/dpid/main.c @@ -15,11 +15,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> /* for ckd_write */ -#include <unistd.h> /* for ckd_write */ -#include <stdlib.h> /* for exit */ -#include <assert.h> /* for assert */ -#include <sys/stat.h> /* for umask */ +#include <errno.h> /* for ckd_write */ +#include <unistd.h> /* for ckd_write */ +#include <stdlib.h> /* for exit */ +#include <assert.h> /* for assert */ +#include <sys/stat.h> /* for umask */ #include "dpid_common.h" #include "dpid.h" @@ -45,7 +45,7 @@ static int start_filter_plugin(struct dp dpi_attr) csz = (socklen_t) sizeof(clnt_addr); - newsock = accept(dpi_attr.socket, (struct sockaddr *) &clnt_addr, &csz); + newsock = accept(dpi_attr.sock_fd, (struct sockaddr *) &clnt_addr, &csz); if (newsock == -1) ERRMSG("start_plugin", "accept", errno); @@ -90,12 +90,12 @@ static int start_filter_plugin(struct dp dpi_attr) static void start_server_plugin(struct dp dpi_attr) { - if (dup2(dpi_attr.socket, STDIN_FILENO) == -1) { + if (dup2(dpi_attr.sock_fd, STDIN_FILENO) == -1) { ERRMSG("start_plugin", "dup2", errno); MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path); exit(1); } - if (a_Misc_close_fd(dpi_attr.socket) == -1) { + if (a_Misc_close_fd(dpi_attr.sock_fd) == -1) { ERRMSG("start_plugin", "close", errno); MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path); exit(1); @@ -220,7 +220,6 @@ static int get_open_max(void) int main(void) { int i, n = 0, open_max; - char *dirname = NULL, *sockdir = NULL; int dpid_idle_timeout = 60 * 60; /* default, in seconds */ struct timeval select_timeout; sigset_t mask_none; @@ -250,6 +249,7 @@ int main(void) /* Get list of available dpis */ numdpis = register_all(&dpi_attr_list); +#if 0 /* Get name of socket directory */ dirname = a_Dpi_sockdir_file(); if ((sockdir = init_sockdir(dirname)) == NULL) { @@ -257,14 +257,16 @@ int main(void) MSG_ERR("Failed to create socket directory\n"); exit(1); } +#endif /* Init and get services list */ fill_services_list(dpi_attr_list, numdpis, &services_list); /* Remove any sockets that may have been leftover from a crash */ - cleanup(sockdir); + //cleanup(); + /* Initialise sockets */ - if ((numsocks = init_srs_socket(sockdir)) == -1) { + if ((numsocks = init_ids_srs_socket()) == -1) { switch (dpi_errno) { case dpid_srs_addrinuse: MSG_ERR("dpid refuses to start, possibly because:\n"); @@ -272,11 +274,12 @@ int main(void) MSG_ERR("\t2) A previous dpid didn't clean up on exit.\n"); exit(1); default: - ERRMSG("main", "init_srs_sockets failed", 0); + //ERRMSG("main", "init_srs_socket failed", 0); + ERRMSG("main", "init_ids_srs_socket failed", 0); exit(1); } } - numsocks = init_all_dpi_sockets(dpi_attr_list, sockdir); + numsocks = init_all_dpi_sockets(dpi_attr_list); //est_terminator(); /* Do we still want to clean up on an abnormal exit? */ est_dpi_sigchld(); @@ -308,7 +311,7 @@ int main(void) continue; stop_active_dpis(dpi_attr_list, numdpis); - cleanup(sockdir); + //cleanup(); exit(0); } } while (n == -1 && errno == EINTR); @@ -318,42 +321,42 @@ int main(void) exit(1); } /* If the service req socket is selected then service the req. */ - if (FD_ISSET(srs, &selected_set)) { - int sock; - socklen_t csz; - struct sockaddr_un clnt_addr; + if (FD_ISSET(srs_fd, &selected_set)) { + int sock_fd; + socklen_t sin_sz; + struct sockaddr_in sin; char *req = NULL; --n; assert(n >= 0); - csz = (socklen_t) sizeof(clnt_addr); - sock = accept(srs, (struct sockaddr *) &clnt_addr, &csz); - if (sock == -1) { + sin_sz = (socklen_t) sizeof(sin); + sock_fd = accept(srs_fd, (struct sockaddr *)&sin, &sin_sz); + if (sock_fd == -1) { ERRMSG("main", "accept", errno); MSG_ERR("accept on srs socket failed\n"); MSG_ERR("service pending connections, and continue\n"); } else { int command; - req = get_request(sock); - command = get_command(sock, req); + req = get_request(sock_fd); + command = get_command(sock_fd, req); switch (command) { case BYE_CMD: stop_active_dpis(dpi_attr_list, numdpis); - cleanup(sockdir); + //cleanup(); exit(0); break; case CHECK_SERVER_CMD: - send_sockpath(sock, req, dpi_attr_list); + send_sockport(sock_fd, req, dpi_attr_list); break; case REGISTER_ALL_CMD: - register_all_cmd(sockdir); + register_all_cmd(); break; case UNKNOWN_CMD: { char *d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "DpiError", "Unknown command"); - (void) CKD_WRITE(sock, d_cmd); + (void) CKD_WRITE(sock_fd, d_cmd); dFree(d_cmd); ERRMSG("main", "Unknown command", 0); MSG_ERR(" for request: %s\n", req); @@ -365,14 +368,14 @@ int main(void) } if (req) free(req); - a_Misc_close_fd(sock); + a_Misc_close_fd(sock_fd); } } /* While there's a request on one of the plugin sockets * find the matching plugin and start it. */ for (i = 0; n > 0 && i < numdpis; i++) { - if (FD_ISSET(dpi_attr_list[i].socket, &selected_set)) { + if (FD_ISSET(dpi_attr_list[i].sock_fd, &selected_set)) { --n; assert(n >= 0); @@ -386,11 +389,12 @@ int main(void) * on its socket */ numsocks--; assert(numsocks >= 0); - FD_CLR(dpi_attr_list[i].socket, &sock_set); + FD_CLR(dpi_attr_list[i].sock_fd, &sock_set); if ((dpi_attr_list[i].pid = fork()) == -1) { ERRMSG("main", "fork", errno); /* exit(1); */ } else if (dpi_attr_list[i].pid == 0) { + /* child */ (void) sigprocmask(SIG_SETMASK, &mask_none, NULL); start_server_plugin(dpi_attr_list[i]); } diff --git a/src/IO/Url.h b/src/IO/Url.h index f144bfad..95919f11 100644 --- a/src/IO/Url.h +++ b/src/IO/Url.h @@ -28,7 +28,7 @@ void a_Dpi_ccc (int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2); char *a_Dpi_send_blocking_cmd(const char *server_name, const char *cmd); -void a_Dpi_bye_dpid(void); +void a_Dpi_dillo_exit(void); void a_Dpi_init(void); diff --git a/src/IO/dpi.c b/src/IO/dpi.c index 7d5b550c..6f1c0a97 100644 --- a/src/IO/dpi.c +++ b/src/IO/dpi.c @@ -24,6 +24,7 @@ #include <string.h> #include <stdio.h> #include <errno.h> /* for errno */ +#include <fcntl.h> #include <sys/socket.h> #include <sys/un.h> @@ -335,76 +336,57 @@ static int Dpi_start_dpid(void) } /* - * Make a connection test for a UDS. - * Return: 0 OK, 1 Not working. + * Read dpid's communication keys from its saved file. + * Return value: 1 on success, -1 on error. */ -static int Dpi_check_uds(char *uds_name) +static int Dpi_read_comm_keys(int *port) { - struct sockaddr_un pun; - int SockFD, ret = 1; - - if (access(uds_name, W_OK) == 0) { - /* socket connection test */ - memset(&pun, 0, sizeof(struct sockaddr_un)); - pun.sun_family = AF_LOCAL; - strncpy(pun.sun_path, uds_name, sizeof (pun.sun_path)); - - if ((SockFD = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1 || - connect(SockFD, (struct sockaddr *) &pun, D_SUN_LEN(&pun)) == -1) { - MSG("Dpi_check_uds: %s %s\n", dStrerror(errno), uds_name); - } else { - Dpi_close_fd(SockFD); - ret = 0; - } + FILE *In; + char *fname, *rcline = NULL; + int ret = -1; + + fname = dStrconcat(dGethomedir(), "/.dillo/dpid_comm_keys", NULL); + if ((In = fopen(fname, "r")) == NULL) { + MSG_ERR("[Dpi_read_comm_keys] %s\n", dStrerror(errno)); + } else if ((rcline = dGetline(In)) == NULL) { + MSG_ERR("[Dpi_read_comm_keys] empty file: %s\n", fname); + } else { + *port = strtol(rcline, NULL, 10); + ret = 1; } + dFree(rcline); + dFree(fname); + return ret; } /* - * Return the directory where the UDS are in, - * NULL if it can't be found. + * Make a connection test for a IDS. + * Return: 1 OK, -1 Not working. */ -static char *Dpi_get_dpid_uds_dir(void) +static int Dpi_check_dpid_ids() { - FILE *in; - char *saved_name_filename; /* :) */ - char buf[256], *dpid_uds_dir, *p = NULL, *nl; - - saved_name_filename = - dStrconcat(dGethomedir(), "/.dillo/dpi_socket_dir", NULL); - in = fopen(saved_name_filename, "r"); - dFree(saved_name_filename); - - if (in != NULL) { - dpid_uds_dir = fgets(buf, sizeof(buf), in); - fclose(in); - if (dpid_uds_dir) { - if ((nl = strchr(dpid_uds_dir, '\n'))) { - *nl = 0; - } - if (access(dpid_uds_dir, F_OK) == 0) { - p = dStrdup(dpid_uds_dir); - _MSG("Dpi_get_dpid_uds_dir:: %s\n", p); - } + struct sockaddr_in sin; + const socklen_t sin_sz = sizeof(sin); + int sock_fd, dpid_port, ret = -1; + + /* socket connection test */ + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + if (Dpi_read_comm_keys(&dpid_port) != -1) { + sin.sin_port = htons(dpid_port); + if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + MSG("Dpi_check_dpid_ids: sock_fd=%d %s\n", sock_fd, dStrerror(errno)); + } else if (connect(sock_fd, (struct sockaddr *)&sin, sin_sz) == -1) { + MSG("Dpi_check_dpid_ids: %s\n", dStrerror(errno)); + } else { + Dpi_close_fd(sock_fd); + ret = 1; } } - - _MSG("Dpi_get_dpid_uds_dir: %s \n", dStrerror(errno)); - return p; -} - -/* - * Return the dpid's UDS name, NULL on failure. - */ -static char *Dpi_get_dpid_uds_name(void) -{ - char *dpid_uds_dir, *dpid_uds_name = NULL; - - if ((dpid_uds_dir = Dpi_get_dpid_uds_dir()) != NULL) - dpid_uds_name= dStrconcat(dpid_uds_dir, "/", "dpid.srs", NULL); - - dFree(dpid_uds_dir); - return dpid_uds_name; + return ret; } /* @@ -414,20 +396,16 @@ static char *Dpi_get_dpid_uds_name(void) static int Dpi_check_dpid(int num_tries) { static int starting = 0; - char *dpid_uds_name; int check_st = 1, ret = 2; - if ((dpid_uds_name = Dpi_get_dpid_uds_name())) - check_st = Dpi_check_uds(dpid_uds_name); - - _MSG("Dpi_check_dpid: dpid_uds_name=%s, check_st=%d\n", - dpid_uds_name, check_st); + check_st = Dpi_check_dpid_ids(); + MSG("Dpi_check_dpid: check_st=%d\n", check_st); - if (check_st == 0) { + if (check_st == 1) { /* connection test with dpi server passed */ starting = 0; ret = 0; - } else if (!dpid_uds_name || check_st) { + } else { if (!starting) { /* start dpid */ if (Dpi_start_dpid() == 0) { @@ -435,6 +413,7 @@ static int Dpi_check_dpid(int num_tries) ret = 1; } } else if (++starting < num_tries) { + /* starting */ ret = 1; } else { /* we waited too much, report an error... */ @@ -442,7 +421,6 @@ static int Dpi_check_dpid(int num_tries) } } - dFree(dpid_uds_name); _MSG("Dpi_check_dpid:: %s\n", (ret == 0) ? "OK" : (ret == 1 ? "EAGAIN" : "ERROR")); return ret; @@ -466,59 +444,69 @@ static int Dpi_blocking_start_dpid(void) } /* - * Return the UDS name of a dpi server. + * Return the dpi server's port number, or -1 on error. * (A query is sent to dpid and then its answer parsed) * note: as the available servers and/or the dpi socket directory can * change at any time, we'll ask each time. If someday we find * that connecting each time significantly degrades performance, * an optimized approach can be tried. + * TODO: here we should use the credentials in ~/.dillo/dpid_comm_keys + * (dpid port and password). */ -static char *Dpi_get_server_uds_name(const char *server_name) +int Dpi_get_server_port(const char *server_name) { - char *dpid_uds_dir, *dpid_uds_name = NULL, - *server_uds_name = NULL; - int st; - - dReturn_val_if_fail (server_name != NULL, NULL); - _MSG("Dpi_get_server_uds_name:: server_name = [%s]\n", server_name); - - dpid_uds_dir = Dpi_get_dpid_uds_dir(); - if (dpid_uds_dir) { - struct sockaddr_un dpid; - int sock, req_sz, rdlen; - char buf[128], *cmd, *request, *rply; - size_t buflen; - - /* Get the server's uds name from dpid */ - sock = socket(AF_LOCAL, SOCK_STREAM, 0); - dpid.sun_family = AF_LOCAL; - dpid_uds_name = dStrconcat(dpid_uds_dir, "/", "dpid.srs", NULL); - _MSG("dpid_uds_name = [%s]\n", dpid_uds_name); - strncpy(dpid.sun_path, dpid_uds_name, sizeof(dpid.sun_path)); - - if (connect(sock, (struct sockaddr *) &dpid, D_SUN_LEN(&dpid)) == -1) - perror("connect"); - /* ask dpid to check the server plugin and send its UDS name back */ + int sock_fd, req_sz, rdlen, dpi_port; + int st, dpid_port, ret = -1, ok = 0; + struct sockaddr_in sin; + char buf[128], *cmd, *request, *rply = NULL, *port_str; + size_t buflen; + socklen_t sin_sz; + + dReturn_val_if_fail (server_name != NULL, ret); + _MSG("Dpi_get_server_port:: server_name = [%s]\n", server_name); + + /* Read dpid's port from saved file */ + if (Dpi_read_comm_keys(&dpid_port) != -1) { + ok = 1; + } + if (ok) { + /* Connect a socket with dpid */ + sin_sz = sizeof(sin); + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sin.sin_port = htons(dpid_port); + if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 || + connect(sock_fd, (struct sockaddr *)&sin, sin_sz) == -1) { + MSG("Dpi_get_server_port: %s\n", dStrerror(errno)); + ok = 0; + } + } + if (ok) { + /* ask dpid to check the dpi and send its port number back */ request = a_Dpip_build_cmd("cmd=%s msg=%s", "check_server", server_name); _MSG("[%s]\n", request); - do - st = write(sock, request, strlen(request)); - while (st < 0 && errno == EINTR); - if (st < 0 && errno != EINTR) - perror("writing request"); + do { + st = write(sock_fd, request, strlen(request)); + } while (st < 0 && errno == EINTR); + if (st < 0 && errno != EINTR) { + MSG("Dpi_get_server_port: %s\n", dStrerror(errno)); + ok = 0; + } dFree(request); - shutdown(sock, 1); /* signals no more writes to dpid */ - + shutdown(sock_fd, 1); /* signals no more writes to dpid */ + } + if (ok) { /* Get the reply */ - rply = NULL; buf[0] = '\0'; buflen = sizeof(buf)/sizeof(buf[0]); - for (req_sz = 0; (rdlen = read(sock, buf, buflen)) != 0; + for (req_sz = 0; (rdlen = read(sock_fd, buf, buflen)) != 0; req_sz += rdlen) { if (rdlen == -1 && errno == EINTR) continue; if (rdlen == -1) { - perror(" ** Dpi_get_server_uds_name **"); + MSG("Dpi_get_server_port: %s\n", dStrerror(errno)); + ok = 0; break; } rply = dRealloc(rply, (uint_t)(req_sz + rdlen + 1)); @@ -526,69 +514,70 @@ static char *Dpi_get_server_uds_name(const char *server_name) rply[0] = '\0'; strncat(rply, buf, (size_t)rdlen); } - Dpi_close_fd(sock); - _MSG("rply = [%s]\n", rply); - - /* Parse reply */ + Dpi_close_fd(sock_fd); if (rdlen == 0 && rply) { - cmd = a_Dpip_get_attr(rply, "cmd"); - if (strcmp(cmd, "send_data") == 0) - server_uds_name = a_Dpip_get_attr(rply, "msg"); - dFree(cmd); - dFree(rply); + _MSG("rply = [%s]\n", rply); + ok = 1; } } - dFree(dpid_uds_dir); - dFree(dpid_uds_name); - _MSG("Dpi_get_server_uds_name:: %s\n", server_uds_name); - return server_uds_name; + if (ok) { + /* Parse reply */ + cmd = a_Dpip_get_attr(rply, "cmd"); + if (strcmp(cmd, "send_data") == 0) { + port_str = a_Dpip_get_attr(rply, "msg"); + MSG("Dpi_get_server_port: rply=%s\n", rply); + MSG("Dpi_get_server_port: port_str=%s\n", port_str); + dpi_port = strtol(port_str, NULL, 10); + dFree(port_str); + ok = 1; + } + dFree(cmd); + } + dFree(rply); + + return ok ? dpi_port : -1; } /* * Connect a socket to a dpi server and return the socket's FD. - * We have to ask 'dpid' (dpi daemon) for the UDS of the target dpi server. + * We have to ask 'dpid' (dpi daemon) for the port of the target dpi server. * Once we have it, then the proper file descriptor is returned (-1 on error). */ static int Dpi_connect_socket(const char *server_name, int retry) { - char *server_uds_name; - struct sockaddr_un pun; - int SockFD, err; + struct sockaddr_in sin; + int sock_fd, err, dpi_port; - /* Query dpid for the UDS name for this server */ - server_uds_name = Dpi_get_server_uds_name(server_name); - _MSG("server_uds_name = [%s]\n", server_uds_name); - - if (access(server_uds_name, F_OK) != 0) { - MSG("server socket was NOT found\n"); + /* Query dpid for the port number for this server */ + if ((dpi_port = Dpi_get_server_port(server_name)) == -1) { + MSG("Dpi_connect_socket:: can't get port number for %s\n", server_name); return -1; } + MSG("Dpi_connect_socket: server=%s port=%d\n", server_name, dpi_port); /* connect with this server's socket */ - memset(&pun, 0, sizeof(struct sockaddr_un)); - pun.sun_family = AF_LOCAL; - strncpy(pun.sun_path, server_uds_name, sizeof (pun.sun_path)); - dFree(server_uds_name); + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sin.sin_port = htons(dpi_port); - if ((SockFD = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) + if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("[dpi::socket]"); - else if (connect(SockFD, (void*)&pun, D_SUN_LEN(&pun)) == -1) { + } else if (connect(sock_fd, (void*)&sin, sizeof(sin)) == -1) { err = errno; - SockFD = -1; + sock_fd = -1; MSG("[dpi::connect] errno:%d %s\n", errno, dStrerror(errno)); if (retry) { switch (err) { case ECONNREFUSED: case EBADF: case ENOTSOCK: case EADDRNOTAVAIL: - /* the server may crash and its socket name survive */ - unlink(pun.sun_path); - SockFD = Dpi_connect_socket(server_name, FALSE); + sock_fd = Dpi_connect_socket(server_name, FALSE); break; } } } - return SockFD; + return sock_fd; } @@ -707,38 +696,13 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info, } } -/*! Send DpiBye to dpid - * Note: currently disabled. Maybe it'd be better to have a - * dpid_idle_timeout variable in the config file. +/*! Let dpid know dillo is no longer running. + * Note: currently disabled. It may serve to let the cookies dpi know + * when to expire session cookies. */ -void a_Dpi_bye_dpid() +void a_Dpi_dillo_exit() { - char *DpiBye_cmd; - struct sockaddr_un sa; - size_t sun_path_len, addr_len; - char *srs_name; - int new_socket; - - srs_name = Dpi_get_dpid_uds_name(); - sun_path_len = sizeof(sa.sun_path); - - sa.sun_family = AF_LOCAL; - if ((new_socket = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { - MSG("a_Dpi_bye_dpid: %s\n", dStrerror(errno)); - } - strncpy(sa.sun_path, srs_name, sizeof (sa.sun_path)); - addr_len = D_SUN_LEN(&sa); - if (connect(new_socket, (struct sockaddr *) &sa, addr_len) == -1) { - MSG("a_Dpi_bye_dpid: %s\n", dStrerror(errno)); - MSG("%s\n", sa.sun_path); - } - DpiBye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye"); - if (write(new_socket, DpiBye_cmd, strlen(DpiBye_cmd)) != - (ssize_t) strlen(DpiBye_cmd)) - MSG_WARN("Failed to send DpiBye\n"); - dFree(DpiBye_cmd); - Dpi_close_fd(new_socket); } diff --git a/src/dillo.cc b/src/dillo.cc index 5e1bbd3e..0a8c219c 100644 --- a/src/dillo.cc +++ b/src/dillo.cc @@ -368,7 +368,7 @@ int main(int argc, char **argv) Paths::free(); /* TODO: auth, css */ - //a_Dpi_bye_dpid(); + //a_Dpi_dillo_exit(); MSG("Dillo: normal exit!\n"); return 0; } |