summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ppp/bundle.c216
-rw-r--r--usr.sbin/ppp/bundle.h3
-rw-r--r--usr.sbin/ppp/command.c2
-rw-r--r--usr.sbin/ppp/datalink.c9
-rw-r--r--usr.sbin/ppp/datalink.h2
-rw-r--r--usr.sbin/ppp/ether.c2
-rw-r--r--usr.sbin/ppp/i4b.c2
-rw-r--r--usr.sbin/ppp/mp.c59
-rw-r--r--usr.sbin/ppp/physical.c32
-rw-r--r--usr.sbin/ppp/physical.h8
-rw-r--r--usr.sbin/ppp/tty.c2
-rw-r--r--usr.sbin/ppp/udp.c2
12 files changed, 205 insertions, 134 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index 94340143..0f62c7b 100644
--- a/usr.sbin/ppp/bundle.c
+++ b/usr.sbin/ppp/bundle.c
@@ -95,13 +95,11 @@
#include "ip.h"
#include "iface.h"
-#define SCATTER_SEGMENTS 6 /* version, datalink, name, physical,
- throughput, device */
-#define SOCKET_OVERHEAD 100 /* additional buffer space for large
- {recv,send}msg() calls */
+#define SCATTER_SEGMENTS 6 /* version, datalink, name, physical,
+ throughput, device */
-#define SEND_MAXFD 2 /* Max file descriptors passed through
- the local domain socket */
+#define SEND_MAXFD 3 /* Max file descriptors passed through
+ the local domain socket */
static int bundle_RemainingIdleTime(struct bundle *);
@@ -926,7 +924,8 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
log_Printf(LogTCPIP, "bundle_SetRoute failure:\n");
log_Printf(LogTCPIP, "bundle_SetRoute: Cmd = %s\n", cmdstr);
log_Printf(LogTCPIP, "bundle_SetRoute: Dst = %s\n", inet_ntoa(dst));
- log_Printf(LogTCPIP, "bundle_SetRoute: Gateway = %s\n", inet_ntoa(gateway));
+ log_Printf(LogTCPIP, "bundle_SetRoute: Gateway = %s\n",
+ inet_ntoa(gateway));
log_Printf(LogTCPIP, "bundle_SetRoute: Mask = %s\n", inet_ntoa(mask));
failed:
if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
@@ -1329,55 +1328,78 @@ bundle_GetLabel(struct bundle *bundle)
return *bundle->cfg.label ? bundle->cfg.label : NULL;
}
+int
+bundle_LinkSize()
+{
+ struct iovec iov[SCATTER_SEGMENTS];
+ int niov, expect, f;
+
+ iov[0].iov_len = strlen(Version) + 1;
+ iov[0].iov_base = NULL;
+ niov = 1;
+ if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) {
+ log_Printf(LogERROR, "Cannot determine space required for link\n");
+ return 0;
+ }
+
+ for (f = expect = 0; f < niov; f++)
+ expect += iov[f].iov_len;
+
+ return expect;
+}
+
void
-bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
+bundle_ReceiveDatalink(struct bundle *bundle, int s)
{
- char cmsgbuf[(sizeof(struct cmsghdr) + sizeof(int)) * SEND_MAXFD];
+ char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
+ int niov, expect, f, *fd, nfd, onfd;
+ struct iovec iov[SCATTER_SEGMENTS];
struct cmsghdr *cmsg;
struct msghdr msg;
- struct iovec iov[SCATTER_SEGMENTS];
struct datalink *dl;
- int niov, expect, f, fd[SEND_MAXFD], nfd, onfd;
pid_t pid;
+ char ack;
log_Printf(LogPHASE, "Receiving datalink\n");
- /* Create our scatter/gather array */
- niov = 1;
-
+ /*
+ * Create our scatter/gather array - passing NULL gets the space
+ * allocation requirement rather than actually flattening the
+ * structures.
+ */
iov[0].iov_len = strlen(Version) + 1;
- iov[0].iov_base = (char *)malloc(iov[0].iov_len);
- if (datalink2iov(NULL, iov, &niov, sizeof iov / sizeof *iov,
- NULL, NULL, 0) == -1) {
- close(s);
+ iov[0].iov_base = NULL;
+ niov = 1;
+ if (datalink2iov(NULL, iov, &niov, SCATTER_SEGMENTS, NULL, NULL) == -1) {
+ log_Printf(LogERROR, "Cannot determine space required for link\n");
return;
}
- pid = getpid();
- write(s, &pid, sizeof pid);
-
- for (f = expect = 0; f < niov; f++)
+ /* Allocate the scatter/gather array for recvmsg() */
+ for (f = expect = 0; f < niov; f++) {
+ if ((iov[f].iov_base = malloc(iov[f].iov_len)) == NULL) {
+ log_Printf(LogERROR, "Cannot allocate space to receive link\n");
+ return;
+ }
expect += iov[f].iov_len;
+ }
/* Set up our message */
- for (f = 0; f < SEND_MAXFD; f++) {
- cmsg = (struct cmsghdr *)(cmsgbuf + f * sizeof(struct cmsghdr));
- cmsg->cmsg_len = sizeof *cmsg + sizeof(int);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = 0;
- }
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ cmsg->cmsg_len = sizeof cmsgbuf;
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = 0;
memset(&msg, '\0', sizeof msg);
- msg.msg_name = (caddr_t)sun;
- msg.msg_namelen = sizeof *sun;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = niov;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof cmsgbuf;
log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", expect);
- f = expect + 100;
- setsockopt(s, SOL_SOCKET, SO_RCVBUF, &f, sizeof f);
+
if ((f = recvmsg(s, &msg, MSG_WAITALL)) != expect) {
if (f == -1)
log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno));
@@ -1385,24 +1407,24 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", f, expect);
while (niov--)
free(iov[niov].iov_base);
- close(s);
return;
}
- write(s, "!", 1); /* ACK */
- close(s);
-
- for (nfd = 0; nfd < SEND_MAXFD; nfd++) {
- cmsg = (struct cmsghdr *)(cmsgbuf + nfd * sizeof(struct cmsghdr));
- if (cmsg->cmsg_len == sizeof *cmsg + sizeof(int) &&
- cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
- fd[nfd] = *(int *)CMSG_DATA(cmsg);
- else
- break;
+ if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
+ log_Printf(LogERROR, "Recvmsg: no descriptors received !\n");
+ while (niov--)
+ free(iov[niov].iov_base);
+ return;
}
- if (nfd == 0) {
- log_Printf(LogERROR, "Recvmsg: no descriptors received !\n");
+ fd = (int *)(cmsg + 1);
+ nfd = (cmsg->cmsg_len - sizeof *cmsg) / sizeof(int);
+
+ if (nfd < 2) {
+ log_Printf(LogERROR, "Recvmsg: %d descriptor%s received (too few) !\n",
+ nfd, nfd == 1 ? "" : "s");
+ while (nfd--)
+ close(fd[nfd]);
while (niov--)
free(iov[niov].iov_base);
return;
@@ -1414,31 +1436,35 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
*/
log_Printf(LogDEBUG, "Receiving device descriptor\n");
- nfd--; /* Don't include p->fd */
-
if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) {
log_Printf(LogWARN, "Cannot receive datalink, incorrect version"
" (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len,
(char *)iov[0].iov_base, Version);
- while (nfd)
- close(fd[nfd--]);
- close(fd[0]);
+ while (nfd--)
+ close(fd[nfd]);
while (niov--)
free(iov[niov].iov_base);
return;
}
- niov = 1;
- onfd = nfd;
+ onfd = nfd; /* We've got this many in our array */
+ nfd -= 2; /* Don't include p->fd and our reply descriptor */
+ niov = 1; /* Skip the version id */
dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, fd[0],
- fd + 1, &nfd);
+ fd + 2, &nfd);
if (dl) {
+ pid = getpid();
+ write(fd[1], &pid, sizeof pid); /* Please hand me any locks */
+ read(fd[1], &ack, 1); /* Thanks (ACK) ! */
+ close(fd[1]);
+
if (nfd) {
log_Printf(LogERROR, "bundle_ReceiveDatalink: Failed to handle %d "
- "auxiliary file descriptors\n", nfd);
+ "auxiliary file descriptors (%d remain)\n", onfd, nfd);
datalink_Destroy(dl);
while (nfd--)
close(fd[onfd--]);
+ close(fd[0]);
} else {
bundle_DatalinkLinkin(bundle, dl);
datalink_AuthOk(dl);
@@ -1448,6 +1474,7 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
while (nfd--)
close(fd[onfd--]);
close(fd[0]);
+ close(fd[1]);
}
free(iov[0].iov_base);
@@ -1456,15 +1483,25 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
void
bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
{
- char cmsgbuf[(sizeof(struct cmsghdr) + sizeof(int)) * SEND_MAXFD], ack;
+ char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
+ const char *constlock;
+ char *lock;
struct cmsghdr *cmsg;
struct msghdr msg;
struct iovec iov[SCATTER_SEGMENTS];
- int niov, f, expect, newsid, fd[SEND_MAXFD], nfd;
+ int niov, f, expect, newsid, fd[SEND_MAXFD], nfd, reply[2], got;
pid_t newpid;
log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name);
+ /* Record the base device name for a lock transfer later */
+ constlock = physical_LockedDevice(dl->physical);
+ if (constlock) {
+ lock = alloca(strlen(constlock) + 1);
+ strcpy(lock, constlock);
+ } else
+ lock = NULL;
+
bundle_LinkClosed(dl->bundle, dl);
bundle_DatalinkLinkout(dl->bundle, dl);
@@ -1474,30 +1511,33 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
niov = 1;
nfd = 0;
- read(s, &newpid, sizeof newpid);
- fd[0] = datalink2iov(dl, iov, &niov, sizeof iov / sizeof *iov,
- fd + 1, &nfd, newpid);
+ fd[0] = datalink2iov(dl, iov, &niov, SCATTER_SEGMENTS, fd + 2, &nfd);
- if (fd[0] != -1) {
- nfd++; /* Include fd[0] */
+ if (fd[0] != -1 && socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, reply) != -1) {
+ /*
+ * fd[1] is used to get the peer process id back, then to confirm that
+ * we've transferred any device locks to that process id.
+ */
+ fd[1] = reply[1];
+ nfd += 2; /* Include fd[0] and fd[1] */
memset(&msg, '\0', sizeof msg);
- msg.msg_name = (caddr_t)sun;
- msg.msg_namelen = sizeof *sun;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = niov;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof *cmsg + sizeof(int) * nfd;
+ msg.msg_flags = 0;
- for (f = 0; f < nfd; f++) {
- cmsg = (struct cmsghdr *)(cmsgbuf + f * sizeof(struct cmsghdr));
- cmsg->cmsg_len = sizeof *cmsg + sizeof(int);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- *(int *)CMSG_DATA(cmsg) = fd[f];
- }
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ cmsg->cmsg_len = msg.msg_controllen;
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
- msg.msg_control = cmsgbuf;
- msg.msg_controllen = (sizeof *cmsg + sizeof(int)) * nfd;
+ for (f = 0; f < nfd; f++)
+ *((int *)(cmsg + 1) + f) = fd[f];
for (f = expect = 0; f < niov; f++)
expect += iov[f].iov_len;
@@ -1505,19 +1545,33 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
log_Printf(LogDEBUG, "Sending %d descriptor%s and %d bytes in scatter"
"/gather array\n", nfd, nfd == 1 ? "" : "s", expect);
- f = expect + SOCKET_OVERHEAD;
- setsockopt(s, SOL_SOCKET, SO_SNDBUF, &f, sizeof f);
- if (sendmsg(s, &msg, 0) == -1)
- log_Printf(LogERROR, "Failed sendmsg: %s\n", strerror(errno));
- /* We must get the ACK before closing the descriptor ! */
- read(s, &ack, 1);
+ if ((got = sendmsg(s, &msg, 0)) == -1)
+ log_Printf(LogERROR, "Failed sendmsg: %s: %s\n",
+ sun->sun_path, strerror(errno));
+ else if (got != expect)
+ log_Printf(LogERROR, "Failed sendmsg: %s: Only sent %d of %d\n",
+ sun->sun_path, got, expect);
+ else {
+ /* We must get the ACK before closing the descriptor ! */
+ int res;
+
+ read(reply[0], &newpid, sizeof newpid);
+ log_Printf(LogDEBUG, "Received confirmation from pid %d\n", (int)newpid);
+ if (lock && (res = ID0uu_lock_txfr(lock, newpid)) != UU_LOCK_OK)
+ log_Printf(LogPHASE, "uu_lock_txfr: %s\n", uu_lockerr(res));
+
+ write(reply[1], "!", 1); /* Thanks (ACK) ! */
+ }
+
+ close(reply[0]);
+ close(reply[1]);
newsid = Enabled(dl->bundle, OPT_KEEPSESSION) ||
tcgetpgrp(fd[0]) == getpgrp();
while (nfd)
close(fd[--nfd]);
if (newsid)
- bundle_setsid(dl->bundle, 1);
+ bundle_setsid(dl->bundle, got != -1);
}
close(s);
@@ -1630,7 +1684,7 @@ bundle_setsid(struct bundle *bundle, int holdsession)
physical_ChangedPid(dl->physical, pid);
write(fds[1], "!", 1); /* done */
close(fds[1]);
- exit(0);
+ _exit(0);
break;
}
break;
@@ -1672,7 +1726,7 @@ bundle_setsid(struct bundle *bundle, int holdsession)
*/
pause();
}
- exit(0);
+ _exit(0);
break;
}
}
diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h
index a56860b..d987c8a 100644
--- a/usr.sbin/ppp/bundle.h
+++ b/usr.sbin/ppp/bundle.h
@@ -174,7 +174,8 @@ extern void bundle_CleanDatalinks(struct bundle *);
extern void bundle_SetLabel(struct bundle *, const char *);
extern const char *bundle_GetLabel(struct bundle *);
extern void bundle_SendDatalink(struct datalink *, int, struct sockaddr_un *);
-extern void bundle_ReceiveDatalink(struct bundle *, int, struct sockaddr_un *);
+extern int bundle_LinkSize(void);
+extern void bundle_ReceiveDatalink(struct bundle *, int);
extern int bundle_SetMode(struct bundle *, struct datalink *, int);
extern int bundle_RenameDatalink(struct bundle *, struct datalink *,
const char *);
diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c
index 4096597..0b7d925 100644
--- a/usr.sbin/ppp/command.c
+++ b/usr.sbin/ppp/command.c
@@ -151,7 +151,7 @@
#define NEG_SHORTSEQ 52
#define NEG_VJCOMP 53
-const char Version[] = "2.24";
+const char Version[] = "2.25";
static int ShowCommand(struct cmdargs const *);
static int TerminalCommand(struct cmdargs const *);
diff --git a/usr.sbin/ppp/datalink.c b/usr.sbin/ppp/datalink.c
index 31c74c0..9df91c8 100644
--- a/usr.sbin/ppp/datalink.c
+++ b/usr.sbin/ppp/datalink.c
@@ -1337,7 +1337,7 @@ iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov,
int
datalink2iov(struct datalink *dl, struct iovec *iov, int *niov, int maxiov,
- int *auxfd, int *nauxfd, pid_t newpid)
+ int *auxfd, int *nauxfd)
{
/* If `dl' is NULL, we're allocating before a Fromiov() */
int link_fd;
@@ -1359,14 +1359,13 @@ datalink2iov(struct datalink *dl, struct iovec *iov, int *niov, int maxiov,
return -1;
}
- iov[*niov].iov_base = dl ? dl : malloc(sizeof *dl);
+ iov[*niov].iov_base = (void *)dl;
iov[(*niov)++].iov_len = sizeof *dl;
- iov[*niov].iov_base =
- dl ? realloc(dl->name, DATALINK_MAXNAME) : malloc(DATALINK_MAXNAME);
+ iov[*niov].iov_base = dl ? realloc(dl->name, DATALINK_MAXNAME) : NULL;
iov[(*niov)++].iov_len = DATALINK_MAXNAME;
link_fd = physical2iov(dl ? dl->physical : NULL, iov, niov, maxiov, auxfd,
- nauxfd, newpid);
+ nauxfd);
if (link_fd == -1 && dl) {
free(dl->name);
diff --git a/usr.sbin/ppp/datalink.h b/usr.sbin/ppp/datalink.h
index 9931795..721b3be 100644
--- a/usr.sbin/ppp/datalink.h
+++ b/usr.sbin/ppp/datalink.h
@@ -130,7 +130,7 @@ extern struct datalink *datalink_Clone(struct datalink *, const char *);
extern struct datalink *iov2datalink(struct bundle *, struct iovec *, int *,
int, int, int *, int *);
extern int datalink2iov(struct datalink *, struct iovec *, int *, int, int *,
- int *, pid_t);
+ int *);
extern struct datalink *datalink_Destroy(struct datalink *);
extern void datalink_GotAuthname(struct datalink *, const char *);
extern void datalink_Up(struct datalink *, int, int);
diff --git a/usr.sbin/ppp/ether.c b/usr.sbin/ppp/ether.c
index 77cd5e1..b25cfbf 100644
--- a/usr.sbin/ppp/ether.c
+++ b/usr.sbin/ppp/ether.c
@@ -175,7 +175,7 @@ ether_OpenInfo(struct physical *p)
static void
ether_device2iov(struct device *d, struct iovec *iov, int *niov,
- int maxiov, int *auxfd, int *nauxfd, pid_t newpid)
+ int maxiov, int *auxfd, int *nauxfd)
{
struct etherdevice *dev = device2ether(d);
int sz = physical_MaxDeviceSize();
diff --git a/usr.sbin/ppp/i4b.c b/usr.sbin/ppp/i4b.c
index ccaa76b..eae596c 100644
--- a/usr.sbin/ppp/i4b.c
+++ b/usr.sbin/ppp/i4b.c
@@ -269,7 +269,7 @@ i4b_OpenInfo(struct physical *p)
static void
i4b_device2iov(struct device *d, struct iovec *iov, int *niov,
- int maxiov, int *auxfd, int *nauxfd, pid_t newpid)
+ int maxiov, int *auxfd, int *nauxfd)
{
struct i4bdevice *dev = device2i4b(d);
int sz = physical_MaxDeviceSize();
diff --git a/usr.sbin/ppp/mp.c b/usr.sbin/ppp/mp.c
index 43c5829..e030e35 100644
--- a/usr.sbin/ppp/mp.c
+++ b/usr.sbin/ppp/mp.c
@@ -85,6 +85,18 @@
#include "id.h"
#include "arp.h"
+/*
+ * When we set our MP socket buffer size, we need some extra space
+ * for the kernel to use to transfer the file descriptors and their
+ * control structure. In practice, this seems to be
+ *
+ * sizeof(struct msghdr) + sizeof(int) * SEND_MAXFD
+ *
+ * (see bundle.c for SEND_MAXFD), but as this isn't actually documented,
+ * we just add ``a bit extra''
+ */
+#define SOCKET_OVERHEAD 100
+
void
peerid_Init(struct peerid *peer)
{
@@ -1006,20 +1018,8 @@ static void
mpserver_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
{
struct mpserver *s = descriptor2mpserver(d);
- struct sockaddr in;
- int fd, size;
- size = sizeof in;
- fd = accept(s->fd, &in, &size);
- if (fd < 0) {
- log_Printf(LogERROR, "mpserver_Read: accept(): %s\n", strerror(errno));
- return;
- }
-
- if (in.sa_family == AF_LOCAL)
- bundle_ReceiveDatalink(bundle, fd, (struct sockaddr_un *)&in);
- else
- close(fd);
+ bundle_ReceiveDatalink(bundle, s->fd);
}
static int
@@ -1046,7 +1046,7 @@ mpserver_Init(struct mpserver *s)
int
mpserver_Open(struct mpserver *s, struct peerid *peer)
{
- int f, l;
+ int f, l, bufsz;
mode_t mask;
if (s->fd != -1) {
@@ -1065,15 +1065,28 @@ mpserver_Open(struct mpserver *s, struct peerid *peer)
s->socket.sun_family = AF_LOCAL;
s->socket.sun_len = sizeof s->socket;
- s->fd = ID0socket(PF_LOCAL, SOCK_STREAM, 0);
+ s->fd = ID0socket(PF_LOCAL, SOCK_DGRAM, 0);
if (s->fd < 0) {
- log_Printf(LogERROR, "mpserver: socket: %s\n", strerror(errno));
+ log_Printf(LogERROR, "mpserver: socket(): %s\n", strerror(errno));
return MPSERVER_FAILED;
}
setsockopt(s->fd, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *)&s->socket,
sizeof s->socket);
mask = umask(0177);
+
+ /*
+ * Calculate how big a link is. It's vital that we set our receive
+ * buffer size before binding the socket, otherwise we'll end up with
+ * a sendmsg() failing with ENOBUFS.
+ */
+
+ bufsz = bundle_LinkSize() + SOCKET_OVERHEAD;
+ log_Printf(LogDEBUG, "Setting MP socket buffer size to %d\n", bufsz);
+ if (setsockopt(s->fd, SOL_SOCKET, SO_RCVBUF, &bufsz, sizeof bufsz) == -1)
+ log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", bufsz,
+ strerror(errno));
+
if (ID0bind_un(s->fd, &s->socket) < 0) {
if (errno != EADDRINUSE) {
log_Printf(LogPHASE, "mpserver: can't create bundle socket %s (%s)\n",
@@ -1083,12 +1096,17 @@ mpserver_Open(struct mpserver *s, struct peerid *peer)
s->fd = -1;
return MPSERVER_FAILED;
}
+
+ /* Ok, so we'll play sender... set the send buffer size */
+ if (setsockopt(s->fd, SOL_SOCKET, SO_SNDBUF, &bufsz, sizeof bufsz) == -1)
+ log_Printf(LogERROR, "setsockopt(SO_SNDBUF, %d): %s\n", bufsz,
+ strerror(errno));
umask(mask);
if (ID0connect_un(s->fd, &s->socket) < 0) {
log_Printf(LogPHASE, "mpserver: can't connect to bundle socket %s (%s)\n",
s->socket.sun_path, strerror(errno));
if (errno == ECONNREFUSED)
- log_Printf(LogPHASE, " Has the previous server died badly ?\n");
+ log_Printf(LogPHASE, " The previous server died badly !\n");
close(s->fd);
s->fd = -1;
return MPSERVER_FAILED;
@@ -1098,13 +1116,6 @@ mpserver_Open(struct mpserver *s, struct peerid *peer)
return MPSERVER_CONNECTED;
}
- /* Listen for other ppp invocations that want to donate links */
- if (listen(s->fd, 5) != 0) {
- log_Printf(LogERROR, "mpserver: Unable to listen to socket"
- " - BUNDLE overload?\n");
- mpserver_Close(s);
- }
-
return MPSERVER_LISTENING;
}
diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c
index 97124e0..f8915c9 100644
--- a/usr.sbin/ppp/physical.c
+++ b/usr.sbin/ppp/physical.c
@@ -634,7 +634,7 @@ physical_MaxDeviceSize()
int
physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
- int *auxfd, int *nauxfd, pid_t newpid)
+ int *auxfd, int *nauxfd)
{
struct device *h;
int sz;
@@ -650,8 +650,7 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
timer_Stop(&p->link.lcp.fsm.StoppedTimer);
timer_Stop(&p->link.ccp.fsm.StoppedTimer);
if (p->handler) {
- if (p->handler->device2iov)
- h = p->handler;
+ h = p->handler;
p->handler = (struct device *)(long)p->handler->type;
}
@@ -661,7 +660,6 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
else
p->session_owner = (pid_t)-1;
timer_Stop(&p->link.throughput.Timer);
- physical_ChangedPid(p, newpid);
}
if (*niov + 2 >= maxiov) {
@@ -672,28 +670,27 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
return -1;
}
- iov[*niov].iov_base = p ? (void *)p : malloc(sizeof *p);
+ iov[*niov].iov_base = (void *)p;
iov[*niov].iov_len = sizeof *p;
(*niov)++;
- iov[*niov].iov_base = p ? (void *)p->link.throughput.SampleOctets :
- malloc(SAMPLE_PERIOD * sizeof(long long));
+ iov[*niov].iov_base = p ? (void *)p->link.throughput.SampleOctets : NULL;
iov[*niov].iov_len = SAMPLE_PERIOD * sizeof(long long);
(*niov)++;
sz = physical_MaxDeviceSize();
if (p) {
- if (h)
- (*h->device2iov)(h, iov, niov, maxiov, auxfd, nauxfd, newpid);
+ if (h && h->device2iov)
+ (*h->device2iov)(h, iov, niov, maxiov, auxfd, nauxfd);
else {
iov[*niov].iov_base = malloc(sz);
- if (p->handler)
- memcpy(iov[*niov].iov_base, p->handler, sizeof *p->handler);
+ if (h)
+ memcpy(iov[*niov].iov_base, h, sizeof *h);
iov[*niov].iov_len = sz;
(*niov)++;
}
} else {
- iov[*niov].iov_base = malloc(sz);
+ iov[*niov].iov_base = NULL;
iov[*niov].iov_len = sz;
(*niov)++;
}
@@ -701,10 +698,19 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
return p ? p->fd : 0;
}
+const char *
+physical_LockedDevice(struct physical *p)
+{
+ if (p->fd >= 0 && *p->name.full == '/' && p->type != PHYS_DIRECT)
+ return p->name.base;
+
+ return NULL;
+}
+
void
physical_ChangedPid(struct physical *p, pid_t newpid)
{
- if (p->fd >= 0 && *p->name.full == '/' && p->type != PHYS_DIRECT) {
+ if (physical_LockedDevice(p)) {
int res;
if ((res = ID0uu_lock_txfr(p->name.base, newpid)) != UU_LOCK_OK)
diff --git a/usr.sbin/ppp/physical.h b/usr.sbin/ppp/physical.h
index 0ff589a..c05f28b 100644
--- a/usr.sbin/ppp/physical.h
+++ b/usr.sbin/ppp/physical.h
@@ -28,7 +28,7 @@ struct bundle;
struct ccp;
struct cmdargs;
-/* Device types */
+/* Device types (don't use zero, it'll be confused with NULL in physical2iov */
#define I4B_DEVICE 1
#define TTY_DEVICE 2
#define TCP_DEVICE 3
@@ -59,8 +59,7 @@ struct device {
void (*destroy)(struct physical *);
ssize_t (*read)(struct physical *, void *, size_t);
ssize_t (*write)(struct physical *, const void *, size_t);
- void (*device2iov)(struct device *, struct iovec *, int *, int, int *,
- int *, pid_t);
+ void (*device2iov)(struct device *, struct iovec *, int *, int, int *, int *);
int (*speed)(struct physical *);
const char *(*openinfo)(struct physical *);
};
@@ -134,7 +133,8 @@ extern void physical_Destroy(struct physical *);
extern struct physical *iov2physical(struct datalink *, struct iovec *, int *,
int, int, int *, int *);
extern int physical2iov(struct physical *, struct iovec *, int *, int, int *,
- int *, pid_t);
+ int *);
+extern const char *physical_LockedDevice(struct physical *);
extern void physical_ChangedPid(struct physical *, pid_t);
extern int physical_IsSync(struct physical *);
diff --git a/usr.sbin/ppp/tty.c b/usr.sbin/ppp/tty.c
index db9fddc..54093b1 100644
--- a/usr.sbin/ppp/tty.c
+++ b/usr.sbin/ppp/tty.c
@@ -309,7 +309,7 @@ tty_OpenInfo(struct physical *p)
static void
tty_device2iov(struct device *d, struct iovec *iov, int *niov,
- int maxiov, int *auxfd, int *nauxfd, pid_t newpid)
+ int maxiov, int *auxfd, int *nauxfd)
{
struct ttydevice *dev = device2tty(d);
int sz = physical_MaxDeviceSize();
diff --git a/usr.sbin/ppp/udp.c b/usr.sbin/ppp/udp.c
index c3763dc..d7a2228 100644
--- a/usr.sbin/ppp/udp.c
+++ b/usr.sbin/ppp/udp.c
@@ -116,7 +116,7 @@ udp_Free(struct physical *p)
static void
udp_device2iov(struct device *d, struct iovec *iov, int *niov,
- int maxiov, int *auxfd, int *nauxfd, pid_t newpid)
+ int maxiov, int *auxfd, int *nauxfd)
{
int sz = physical_MaxDeviceSize();
OpenPOWER on IntegriCloud