aboutsummaryrefslogtreecommitdiff
path: root/dpid/dpid.c
diff options
context:
space:
mode:
Diffstat (limited to 'dpid/dpid.c')
-rw-r--r--dpid/dpid.c547
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);