summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/server.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2001-01-26 01:41:34 +0000
committerbrian <brian@FreeBSD.org>2001-01-26 01:41:34 +0000
commit63b65f9457011d370ef859a506f558b2731883d2 (patch)
tree694b69d9cd6e10dc4a8f60f6fc9ebc124e7875db /usr.sbin/ppp/server.c
parenta4be54702c06f4adfd819f74d6f5586d5362b361 (diff)
downloadFreeBSD-src-63b65f9457011d370ef859a506f558b2731883d2.zip
FreeBSD-src-63b65f9457011d370ef859a506f558b2731883d2.tar.gz
Allow ``set server closed'' to close the diagnostic socket.
Allow ``set server open'' to re-open the diagnostic socket. Handle SIGUSR1 by re-opening the diagnostic socket When receiving SIGUSR2 (and in ``set server none''), don't forget the socket details so that ``set server open'' and SIGUSR1 open it again. Don't create the diagnostic socket as uid 0 ! It's far to dangerous.
Diffstat (limited to 'usr.sbin/ppp/server.c')
-rw-r--r--usr.sbin/ppp/server.c150
1 files changed, 111 insertions, 39 deletions
diff --git a/usr.sbin/ppp/server.c b/usr.sbin/ppp/server.c
index a87545c..5d29c8b 100644
--- a/usr.sbin/ppp/server.c
+++ b/usr.sbin/ppp/server.c
@@ -26,7 +26,8 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
+
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -138,7 +139,7 @@ server_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset)
switch (sa->sa_family) {
case AF_LOCAL:
p->src.type = "local";
- strncpy(p->src.from, s->rm, sizeof p->src.from - 1);
+ strncpy(p->src.from, s->cfg.sockname, sizeof p->src.from - 1);
p->src.from[sizeof p->src.from - 1] = '\0';
break;
case AF_INET:
@@ -180,70 +181,115 @@ struct server server = {
-1
};
-int
+enum server_stat
+server_Reopen(struct bundle *bundle)
+{
+ char name[sizeof server.cfg.sockname];
+ u_short port;
+ mode_t mask;
+ enum server_stat ret;
+
+ if (server.cfg.sockname[0] != '\0') {
+ strcpy(name, server.cfg.sockname);
+ mask = server.cfg.mask;
+ server_Close(bundle);
+ if (server.cfg.sockname[0] != '\0')
+ /* blow it away - and hope nobody else is using it */
+ unlink(server.cfg.sockname);
+ ret = server_LocalOpen(bundle, name, mask);
+ } else if (server.cfg.port != 0) {
+ port = server.cfg.port;
+ server_Close(bundle);
+ ret = server_TcpOpen(bundle, port);
+ } else
+ ret = SERVER_UNSET;
+
+ return ret;
+}
+
+enum server_stat
server_LocalOpen(struct bundle *bundle, const char *name, mode_t mask)
{
+ struct sockaddr_un ifsun;
+ mode_t oldmask;
int s;
- if (server.rm && !strcmp(server.rm, name)) {
- if (chmod(server.rm, 0777 & ~mask))
- log_Printf(LogERROR, "Local: chmod: %s\n", strerror(errno));
- return 0;
- }
+ oldmask = (mode_t)-1; /* Silence compiler */
+
+ if (server.cfg.sockname && !strcmp(server.cfg.sockname, name))
+ server_Close(bundle);
- memset(&server.ifsun, '\0', sizeof server.ifsun);
- server.ifsun.sun_len = strlen(name);
- if (server.ifsun.sun_len > sizeof server.ifsun.sun_path - 1) {
+ memset(&ifsun, '\0', sizeof ifsun);
+ ifsun.sun_len = strlen(name);
+ if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
log_Printf(LogERROR, "Local: %s: Path too long\n", name);
- return 2;
+ return SERVER_INVALID;
}
- server.ifsun.sun_family = AF_LOCAL;
- strcpy(server.ifsun.sun_path, name);
+ ifsun.sun_family = AF_LOCAL;
+ strcpy(ifsun.sun_path, name);
- s = ID0socket(PF_LOCAL, SOCK_STREAM, 0);
+ s = socket(PF_LOCAL, SOCK_STREAM, 0);
if (s < 0) {
log_Printf(LogERROR, "Local: socket: %s\n", strerror(errno));
- return 3;
+ goto failed;
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
if (mask != (mode_t)-1)
- mask = umask(mask);
- if (bind(s, (struct sockaddr *)&server.ifsun, sizeof server.ifsun) < 0) {
+ oldmask = umask(mask);
+ if (bind(s, (struct sockaddr *)&ifsun, sizeof ifsun) < 0) {
if (mask != (mode_t)-1)
- umask(mask);
+ umask(oldmask);
log_Printf(LogWARN, "Local: bind: %s\n", strerror(errno));
close(s);
- return 4;
+ goto failed;
}
if (mask != (mode_t)-1)
- umask(mask);
+ umask(oldmask);
if (listen(s, 5) != 0) {
log_Printf(LogERROR, "Local: Unable to listen to socket -"
" BUNDLE overload?\n");
close(s);
- ID0unlink(name);
- return 5;
+ unlink(name);
+ goto failed;
}
server_Close(bundle);
server.fd = s;
- server.rm = server.ifsun.sun_path;
+ server.cfg.port = 0;
+ strncpy(server.cfg.sockname, ifsun.sun_path, sizeof server.cfg.sockname - 1);
+ server.cfg.sockname[sizeof server.cfg.sockname - 1] = '\0';
+ server.cfg.mask = mask;
log_Printf(LogPHASE, "Listening at local socket %s.\n", name);
- return 0;
+
+ return SERVER_OK;
+
+failed:
+ if (server.fd == -1) {
+ server.fd = -1;
+ server.cfg.port = 0;
+ strncpy(server.cfg.sockname, ifsun.sun_path,
+ sizeof server.cfg.sockname - 1);
+ server.cfg.sockname[sizeof server.cfg.sockname - 1] = '\0';
+ server.cfg.mask = mask;
+ }
+ return SERVER_FAILED;
}
-int
-server_TcpOpen(struct bundle *bundle, int port)
+enum server_stat
+server_TcpOpen(struct bundle *bundle, u_short port)
{
struct sockaddr_in ifsin;
int s;
- if (server.port == port)
- return 0;
+ if (server.cfg.port == port)
+ server_Close(bundle);
+
+ if (port == 0)
+ return SERVER_INVALID;
- s = ID0socket(PF_INET, SOCK_STREAM, 0);
+ s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
log_Printf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
- return 7;
+ goto failed;
}
memset(&ifsin, '\0', sizeof ifsin);
ifsin.sin_family = AF_INET;
@@ -253,40 +299,66 @@ server_TcpOpen(struct bundle *bundle, int port)
if (bind(s, (struct sockaddr *)&ifsin, sizeof ifsin) < 0) {
log_Printf(LogWARN, "Tcp: bind: %s\n", strerror(errno));
close(s);
- return 8;
+ goto failed;
}
if (listen(s, 5) != 0) {
log_Printf(LogERROR, "Tcp: Unable to listen to socket: %s\n",
strerror(errno));
close(s);
- return 9;
+ goto failed;
}
server_Close(bundle);
server.fd = s;
- server.port = port;
+ server.cfg.port = port;
+ *server.cfg.sockname = '\0';
+ server.cfg.mask = 0;
log_Printf(LogPHASE, "Listening at port %d.\n", port);
- return 0;
+ return SERVER_OK;
+
+failed:
+ if (server.fd == -1) {
+ server.fd = -1;
+ server.cfg.port = port;
+ *server.cfg.sockname = '\0';
+ server.cfg.mask = 0;
+ }
+ return SERVER_FAILED;
}
int
server_Close(struct bundle *bundle)
{
if (server.fd >= 0) {
- if (server.rm) {
+ if (*server.cfg.sockname != '\0') {
struct sockaddr_un un;
int sz = sizeof un;
if (getsockname(server.fd, (struct sockaddr *)&un, &sz) == 0 &&
un.sun_family == AF_LOCAL && sz == sizeof un)
- ID0unlink(un.sun_path);
- server.rm = NULL;
+ unlink(un.sun_path);
}
close(server.fd);
server.fd = -1;
- server.port = 0;
/* Drop associated prompts */
log_DestroyPrompts(&server);
+
return 1;
}
+
return 0;
}
+
+int
+server_Clear(struct bundle *bundle)
+{
+ int ret;
+
+ ret = server_Close(bundle);
+
+ server.fd = -1;
+ server.cfg.port = 0;
+ *server.cfg.sockname = '\0';
+ server.cfg.mask = 0;
+
+ return ret;
+}
OpenPOWER on IntegriCloud