From 0262adbbcca0da1a4484621308d55849c879fa37 Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Tue, 26 Feb 2013 20:12:25 +0800 Subject: [PATCH] Add a argument to specify the unix control socket --- src/client/lldpcli.8 | 5 +++++ src/client/lldpcli.c | 7 ++++++- src/ctl.c | 6 +++--- src/ctl.h | 6 +++--- src/daemon/lldpd.8 | 4 ++++ src/daemon/lldpd.c | 20 +++++++++++++------- src/daemon/lldpd.h | 3 ++- src/daemon/priv.c | 17 +++++++++++++++-- src/lib/connection.c | 21 ++++++++++++++++----- src/lib/lldpctl.h | 18 ++++++++++++++++++ src/lib/private.h | 3 +++ 11 files changed, 88 insertions(+), 22 deletions(-) diff --git a/src/client/lldpcli.8 b/src/client/lldpcli.8 index dffa7a67..2ef5bc11 100644 --- a/src/client/lldpcli.8 +++ b/src/client/lldpcli.8 @@ -23,11 +23,13 @@ .Sh SYNOPSIS .Nm .Op Fl dv +.Op Fl u Ar file .Op Fl f Ar format .Op Fl c Ar file .Op Ar command ... .Nm lldpctl .Op Fl dv +.Op Fl u Ar file .Op Fl f Ar format .Op Ar interfaces ... .Sh DESCRIPTION @@ -47,6 +49,9 @@ The options are as follows: .Bl -tag -width Ds .It Fl d Enable more debugging information. +.It Fl u +Specify the Unix-domain socket used for communication with +.Xr lldpd 8 . .It Fl v Show .Nm diff --git a/src/client/lldpcli.c b/src/client/lldpcli.c index cba35e4e..189c0de5 100644 --- a/src/client/lldpcli.c +++ b/src/client/lldpcli.c @@ -66,6 +66,7 @@ usage() fprintf(stderr, "\n"); fprintf(stderr, "-d Enable more debugging information.\n"); + fprintf(stderr, "-u Specify the Unix-domain socket used for communication with lldpd(8).\n"); fprintf(stderr, "-f format Choose output format (plain, keyvalue or xml).\n"); if (!is_lldpctl(NULL)) fprintf(stderr, "-c Read the provided configuration file.\n"); @@ -412,6 +413,7 @@ main(int argc, char *argv[]) lldpctl_conn_t *conn = NULL; const char *options = is_lldpctl(argv[0])?"hdvf:":"hdsvf:c:"; + const char *ctlname = lldpctl_get_default_transport(); int gotinputs = 0; struct inputs inputs; TAILQ_INIT(&inputs); @@ -434,6 +436,9 @@ main(int argc, char *argv[]) case 'h': usage(); break; + case 'u': + ctlname = optarg; + break; case 'v': fprintf(stdout, "%s\n", PACKAGE_VERSION); exit(0); @@ -455,7 +460,7 @@ main(int argc, char *argv[]) /* Make a connection */ log_debug("lldpctl", "connect to lldpd"); - conn = lldpctl_new(NULL, NULL, NULL); + conn = lldpctl_new_name(ctlname, NULL, NULL, NULL); if (conn == NULL) goto end; /* Process file inputs */ diff --git a/src/ctl.c b/src/ctl.c index 023ec946..b323c280 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -36,7 +36,7 @@ * @return The socket when successful, -1 otherwise. */ int -ctl_create(char *name) +ctl_create(const char *name) { int s; struct sockaddr_un su; @@ -69,7 +69,7 @@ ctl_create(char *name) * @return The socket when successful, -1 otherwise. */ int -ctl_connect(char *name) +ctl_connect(const char *name) { int s; struct sockaddr_un su; @@ -96,7 +96,7 @@ ctl_connect(char *name) * @param name The name of the Unix socket. */ void -ctl_cleanup(char *name) +ctl_cleanup(const char *name) { log_debug("control", "cleanup control socket"); if (unlink(name) == -1) diff --git a/src/ctl.h b/src/ctl.h index 0bf8fee9..9d019bd7 100644 --- a/src/ctl.h +++ b/src/ctl.h @@ -47,9 +47,9 @@ struct hmsg_header { #define HMSG_MAX_SIZE (1<<19) /* ctl.c */ -int ctl_create(char *); -int ctl_connect(char *); -void ctl_cleanup(char *); +int ctl_create(const char *); +int ctl_connect(const char *); +void ctl_cleanup(const char *); int ctl_msg_send_unserialized(uint8_t **, size_t *, enum hmsg_type, diff --git a/src/daemon/lldpd.8 b/src/daemon/lldpd.8 index 49be54c9..f2a2dfba 100644 --- a/src/daemon/lldpd.8 +++ b/src/daemon/lldpd.8 @@ -27,6 +27,7 @@ .Op Fl P Ar platform .Op Fl X Ar socket .Op Fl m Ar management +.Op Fl u Ar file .Op Fl I Ar interfaces .Op Fl C Ar interfaces .Op Fl M Ar class @@ -183,6 +184,9 @@ only negative patterns are provided, only one IPv4 and one IPv6 addresses are chosen. Otherwise, many of them can be selected. If you want to blacklist IPv6 addresses, you can use .Em !*:* . +.It Fl u Ar file +Specify the Unix-domain socket used for communication with +.Xr lldpctl 8 . .It Fl I Ar interfaces Specify which interface to listen to. Without this option, .Nm diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index 747ef0cf..9fab44b4 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -95,6 +95,7 @@ usage(void) fprintf(stderr, "-S descr Override the default system description.\n"); fprintf(stderr, "-P name Override the default hardware platform.\n"); fprintf(stderr, "-m IP Specify the IPv4 management addresses of this system.\n"); + fprintf(stderr, "-u file Specify the Unix-domain socket used for communication with lldpctl(8).\n"); fprintf(stderr, "-H mode Specify the behaviour when detecting multiple neighbors.\n"); fprintf(stderr, "-I iface Limit interfaces to use.\n"); #ifdef ENABLE_LLDPMED @@ -987,7 +988,7 @@ lldpd_exit(struct lldpd *cfg) struct lldpd_hardware *hardware, *hardware_next; log_debug("main", "exit lldpd"); close(cfg->g_ctl); - priv_ctl_cleanup(); + priv_ctl_cleanup(cfg->g_ctlname); log_debug("main", "cleanup hardware information"); for (hardware = TAILQ_FIRST(&cfg->g_hardware); hardware != NULL; hardware = hardware_next) { @@ -1158,11 +1159,12 @@ lldpd_main(int argc, char *argv[]) int snmp = 0; char *agentx = NULL; /* AgentX socket */ #endif + char *ctlname = LLDPD_CTL_SOCKET; char *mgmtp = NULL; char *cidp = NULL; char *interfaces = NULL; char *popt, opts[] = - "H:vhkrdD:xX:m:4:6:I:C:p:M:P:S:iL:@ "; + "H:vhkrdD:xX:m:u:4:6:I:C:p:M:P:S:iL:@ "; int i, found, advertise_version = 1; #ifdef ENABLE_LLDPMED int lldpmed = 0, noinventory = 0; @@ -1211,6 +1213,9 @@ lldpd_main(int argc, char *argv[]) case 'm': mgmtp = optarg; break; + case 'u': + ctlname = optarg; + break; case 'I': interfaces = optarg; break; @@ -1308,13 +1313,13 @@ lldpd_main(int argc, char *argv[]) /* Create and setup socket */ int retry = 1; log_debug("main", "creating control socket"); - while ((ctl = ctl_create(LLDPD_CTL_SOCKET)) == -1) { + while ((ctl = ctl_create(ctlname)) == -1) { if (retry-- && errno == EADDRINUSE) { /* Check if a daemon is really listening */ int tfd; log_info("main", "unable to create control socket because it already exists"); log_info("main", "check if another instance is running"); - if ((tfd = ctl_connect(LLDPD_CTL_SOCKET)) != -1) { + if ((tfd = ctl_connect(ctlname)) != -1) { /* Another instance is running */ close(tfd); log_warnx("main", "another instance is running, please stop it"); @@ -1322,7 +1327,7 @@ lldpd_main(int argc, char *argv[]) } else if (errno == ECONNREFUSED) { /* Nobody is listening */ log_info("main", "old control socket is present, clean it"); - ctl_cleanup(LLDPD_CTL_SOCKET); + ctl_cleanup(ctlname); continue; } log_warn("main", "cannot determine if another daemon is already running"); @@ -1331,9 +1336,9 @@ lldpd_main(int argc, char *argv[]) log_warn("main", "unable to create control socket"); fatalx("giving up"); } - if (chown(LLDPD_CTL_SOCKET, uid, gid) == -1) + if (chown(ctlname, uid, gid) == -1) log_warn("main", "unable to chown control socket"); - if (chmod(LLDPD_CTL_SOCKET, + if (chmod(ctlname, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP) == -1) log_warn("main", "unable to chmod control socket"); @@ -1385,6 +1390,7 @@ lldpd_main(int argc, char *argv[]) calloc(1, sizeof(struct lldpd))) == NULL) fatal("main", NULL); + cfg->g_ctlname = ctlname; cfg->g_ctl = ctl; cfg->g_config.c_mgmt_pattern = mgmtp; cfg->g_config.c_cid_pattern = cidp; diff --git a/src/daemon/lldpd.h b/src/daemon/lldpd.h index 921ab6a2..e289156f 100644 --- a/src/daemon/lldpd.h +++ b/src/daemon/lldpd.h @@ -105,6 +105,7 @@ struct lldpd { #endif /* USE_SNMP */ /* Unix socket handling */ + const char *g_ctlname; int g_ctl; struct event *g_ctl_event; struct event *g_iface_event; /* Triggered when there is an interface change */ @@ -202,7 +203,7 @@ client_handle_client(struct lldpd *cfg, /* priv.c */ void priv_init(const char*, int, uid_t, gid_t); -void priv_ctl_cleanup(void); +void priv_ctl_cleanup(const char *ctlname); char *priv_gethostbyname(void); #ifdef HOST_OS_LINUX int priv_open(char*); diff --git a/src/daemon/priv.c b/src/daemon/priv.c index 8fdd7c9b..422dded3 100644 --- a/src/daemon/priv.c +++ b/src/daemon/priv.c @@ -99,11 +99,14 @@ priv_ping() /* Proxy for ctl_cleanup */ void -priv_ctl_cleanup() +priv_ctl_cleanup(const char *ctlname) { int cmd, rc; + int len = strlen(ctlname); cmd = PRIV_DELETE_CTL_SOCKET; must_write(remote, &cmd, sizeof(int)); + must_write(remote, &len, sizeof(int)); + must_write(remote, ctlname, len); must_read(remote, &rc, sizeof(int)); } @@ -210,8 +213,18 @@ asroot_ping() static void asroot_ctl_cleanup() { + int len; + char *ctlname; int rc = 0; - ctl_cleanup(LLDPD_CTL_SOCKET); + + must_read(remote, &len, sizeof(int)); + if ((ctlname = (char*)malloc(len+1)) == NULL) + fatal("ctlname", NULL); + + must_read(remote, ctlname, len); + ctlname[len] = 0; + + ctl_cleanup(ctlname); /* Ack */ must_write(remote, &rc, sizeof(int)); diff --git a/src/lib/connection.c b/src/lib/connection.c index 729ee092..3b3227cc 100644 --- a/src/lib/connection.c +++ b/src/lib/connection.c @@ -36,9 +36,9 @@ lldpctl_get_default_transport(void) /* Connect to the remote end */ static int -sync_connect() +sync_connect(lldpctl_conn_t *lldpctl) { - return ctl_connect(LLDPD_CTL_SOCKET); + return ctl_connect(lldpctl->ctlname); } /* Synchronously send data to remote end. */ @@ -50,7 +50,7 @@ sync_send(lldpctl_conn_t *lldpctl, size_t nb; if (conn->fd == -1 && - ((conn->fd = sync_connect()) == -1)) { + ((conn->fd = sync_connect(lldpctl)) == -1)) { return LLDPCTL_ERR_CANNOT_CONNECT; } @@ -70,7 +70,7 @@ sync_recv(lldpctl_conn_t *lldpctl, size_t nb; if (conn->fd == -1 && - ((conn->fd = sync_connect()) == -1)) { + ((conn->fd = sync_connect(lldpctl)) == -1)) { lldpctl->error = LLDPCTL_ERR_CANNOT_CONNECT; return LLDPCTL_ERR_CANNOT_CONNECT; } @@ -83,9 +83,14 @@ sync_recv(lldpctl_conn_t *lldpctl, } - lldpctl_conn_t* lldpctl_new(lldpctl_send_callback send, lldpctl_recv_callback recv, void *user_data) +{ + return lldpctl_new_name(lldpctl_get_default_transport(), send, recv, user_data); +} + +lldpctl_conn_t* +lldpctl_new_name(const char *ctlname, lldpctl_send_callback send, lldpctl_recv_callback recv, void *user_data) { lldpctl_conn_t *conn = NULL; struct lldpctl_conn_sync_t *data = NULL; @@ -97,6 +102,11 @@ lldpctl_new(lldpctl_send_callback send, lldpctl_recv_callback recv, void *user_d if ((conn = calloc(1, sizeof(lldpctl_conn_t))) == NULL) return NULL; + conn->ctlname = strdup(ctlname); + if (conn->ctlname == NULL) { + free(conn); + return NULL; + } if (!send && !recv) { if ((data = malloc(sizeof(struct lldpctl_conn_sync_t))) == NULL) { free(conn); @@ -119,6 +129,7 @@ int lldpctl_release(lldpctl_conn_t *conn) { if (conn == NULL) return 0; + free(conn->ctlname); if (conn->send == sync_send) { struct lldpctl_conn_sync_t *data = conn->user_data; if (data->fd != -1) close(data->fd); diff --git a/src/lib/lldpctl.h b/src/lib/lldpctl.h index 2c19228b..70f60b0b 100644 --- a/src/lib/lldpctl.h +++ b/src/lib/lldpctl.h @@ -177,6 +177,24 @@ ssize_t lldpctl_send(lldpctl_conn_t *conn); lldpctl_conn_t *lldpctl_new(lldpctl_send_callback send, lldpctl_recv_callback recv, void *user_data); +/** + * Allocate a new handler for connecting to lldpd. + * + * @param ctlname the Unix-domain socket to connect to lldpd. + * @param send Callback to be used when sending new data is requested. + * @param recv Callback to be used when receiving new data is requested. + * @param user_data Data to pass to callbacks. + * @return An handler to be used to connect to lldpd or @c NULL in + * case of error. In the later case, the error is probable an + * out of memory condition. + * + * The allocated handler can be released with @c lldpctl_release(). If the + * provided parameters are both @c NULL, default synchronous callbacks will be + * used. + */ +lldpctl_conn_t *lldpctl_new_name(const char *ctlname, lldpctl_send_callback send, + lldpctl_recv_callback recv, void *user_data); + /** * Release resources associated with a connection to lldpd. * diff --git a/src/lib/private.h b/src/lib/private.h index 4308f707..616a38d3 100644 --- a/src/lib/private.h +++ b/src/lib/private.h @@ -22,6 +22,9 @@ /* connection.c */ struct lldpctl_conn_t { + /* the Unix-domain socket to connect to lldpd */ + const char *ctlname; + /* Callback handling */ lldpctl_recv_callback recv; /* Receive callback */ lldpctl_send_callback send; /* Send callback */ -- 2.39.5