diff options
-rw-r--r-- | usr.sbin/ppp/bundle.c | 216 | ||||
-rw-r--r-- | usr.sbin/ppp/bundle.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/command.c | 2 | ||||
-rw-r--r-- | usr.sbin/ppp/datalink.c | 9 | ||||
-rw-r--r-- | usr.sbin/ppp/datalink.h | 2 | ||||
-rw-r--r-- | usr.sbin/ppp/ether.c | 2 | ||||
-rw-r--r-- | usr.sbin/ppp/i4b.c | 2 | ||||
-rw-r--r-- | usr.sbin/ppp/mp.c | 59 | ||||
-rw-r--r-- | usr.sbin/ppp/physical.c | 32 | ||||
-rw-r--r-- | usr.sbin/ppp/physical.h | 8 | ||||
-rw-r--r-- | usr.sbin/ppp/tty.c | 2 | ||||
-rw-r--r-- | usr.sbin/ppp/udp.c | 2 |
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(); |