Deleted Added
full compact
bundle.c (53830) bundle.c (53970)
1/*-
2 * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/usr.sbin/ppp/bundle.c 53830 1999-11-28 15:50:08Z brian $
26 * $FreeBSD: head/usr.sbin/ppp/bundle.c 53970 1999-11-30 23:52:37Z brian $
27 */
28
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <net/if.h>
33#include <net/if_tun.h> /* For TUNSIFMODE & TUNSLMODE */
34#include <arpa/inet.h>

--- 1313 unchanged lines hidden (view full) ---

1348
1349 return expect;
1350}
1351
1352void
1353bundle_ReceiveDatalink(struct bundle *bundle, int s)
1354{
1355 char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
27 */
28
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <net/if.h>
33#include <net/if_tun.h> /* For TUNSIFMODE & TUNSLMODE */
34#include <arpa/inet.h>

--- 1313 unchanged lines hidden (view full) ---

1348
1349 return expect;
1350}
1351
1352void
1353bundle_ReceiveDatalink(struct bundle *bundle, int s)
1354{
1355 char cmsgbuf[sizeof(struct cmsghdr) + sizeof(int) * SEND_MAXFD];
1356 int niov, expect, f, *fd, nfd, onfd;
1356 int niov, expect, f, *fd, nfd, onfd, got;
1357 struct iovec iov[SCATTER_SEGMENTS];
1358 struct cmsghdr *cmsg;
1359 struct msghdr msg;
1360 struct datalink *dl;
1361 pid_t pid;
1357 struct iovec iov[SCATTER_SEGMENTS];
1358 struct cmsghdr *cmsg;
1359 struct msghdr msg;
1360 struct datalink *dl;
1361 pid_t pid;
1362 char ack;
1363
1364 log_Printf(LogPHASE, "Receiving datalink\n");
1365
1366 /*
1367 * Create our scatter/gather array - passing NULL gets the space
1368 * allocation requirement rather than actually flattening the
1369 * structures.
1370 */

--- 6 unchanged lines hidden (view full) ---

1377 }
1378
1379 /* Allocate the scatter/gather array for recvmsg() */
1380 for (f = expect = 0; f < niov; f++) {
1381 if ((iov[f].iov_base = malloc(iov[f].iov_len)) == NULL) {
1382 log_Printf(LogERROR, "Cannot allocate space to receive link\n");
1383 return;
1384 }
1362
1363 log_Printf(LogPHASE, "Receiving datalink\n");
1364
1365 /*
1366 * Create our scatter/gather array - passing NULL gets the space
1367 * allocation requirement rather than actually flattening the
1368 * structures.
1369 */

--- 6 unchanged lines hidden (view full) ---

1376 }
1377
1378 /* Allocate the scatter/gather array for recvmsg() */
1379 for (f = expect = 0; f < niov; f++) {
1380 if ((iov[f].iov_base = malloc(iov[f].iov_len)) == NULL) {
1381 log_Printf(LogERROR, "Cannot allocate space to receive link\n");
1382 return;
1383 }
1385 expect += iov[f].iov_len;
1384 if (f)
1385 expect += iov[f].iov_len;
1386 }
1387
1388 /* Set up our message */
1389 cmsg = (struct cmsghdr *)cmsgbuf;
1390 cmsg->cmsg_len = sizeof cmsgbuf;
1391 cmsg->cmsg_level = SOL_SOCKET;
1392 cmsg->cmsg_type = 0;
1393
1394 memset(&msg, '\0', sizeof msg);
1395 msg.msg_name = NULL;
1396 msg.msg_namelen = 0;
1397 msg.msg_iov = iov;
1386 }
1387
1388 /* Set up our message */
1389 cmsg = (struct cmsghdr *)cmsgbuf;
1390 cmsg->cmsg_len = sizeof cmsgbuf;
1391 cmsg->cmsg_level = SOL_SOCKET;
1392 cmsg->cmsg_type = 0;
1393
1394 memset(&msg, '\0', sizeof msg);
1395 msg.msg_name = NULL;
1396 msg.msg_namelen = 0;
1397 msg.msg_iov = iov;
1398 msg.msg_iovlen = niov;
1398 msg.msg_iovlen = 1; /* Only send the version at the first pass */
1399 msg.msg_control = cmsgbuf;
1400 msg.msg_controllen = sizeof cmsgbuf;
1401
1399 msg.msg_control = cmsgbuf;
1400 msg.msg_controllen = sizeof cmsgbuf;
1401
1402 log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", expect);
1402 log_Printf(LogDEBUG, "Expecting %d scatter/gather bytes\n", iov[0].iov_len);
1403
1403
1404 if ((f = recvmsg(s, &msg, MSG_WAITALL)) != expect) {
1405 if (f == -1)
1404 if ((got = recvmsg(s, &msg, MSG_WAITALL)) != iov[0].iov_len) {
1405 if (got == -1)
1406 log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno));
1407 else
1406 log_Printf(LogERROR, "Failed recvmsg: %s\n", strerror(errno));
1407 else
1408 log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n", f, expect);
1408 log_Printf(LogERROR, "Failed recvmsg: Got %d, not %d\n",
1409 got, iov[0].iov_len);
1409 while (niov--)
1410 free(iov[niov].iov_base);
1411 return;
1412 }
1413
1414 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1415 log_Printf(LogERROR, "Recvmsg: no descriptors received !\n");
1416 while (niov--)

--- 10 unchanged lines hidden (view full) ---

1427 while (nfd--)
1428 close(fd[nfd]);
1429 while (niov--)
1430 free(iov[niov].iov_base);
1431 return;
1432 }
1433
1434 /*
1410 while (niov--)
1411 free(iov[niov].iov_base);
1412 return;
1413 }
1414
1415 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1416 log_Printf(LogERROR, "Recvmsg: no descriptors received !\n");
1417 while (niov--)

--- 10 unchanged lines hidden (view full) ---

1428 while (nfd--)
1429 close(fd[nfd]);
1430 while (niov--)
1431 free(iov[niov].iov_base);
1432 return;
1433 }
1434
1435 /*
1435 * We've successfully received one or more open file descriptors
1436 * through our socket
1436 * We've successfully received two or more open file descriptors
1437 * through our socket, plus a version string. Make sure it's the
1438 * correct version, and drop the connection if it's not.
1437 */
1439 */
1438 log_Printf(LogDEBUG, "Receiving device descriptor\n");
1439
1440 if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) {
1441 log_Printf(LogWARN, "Cannot receive datalink, incorrect version"
1442 " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len,
1443 (char *)iov[0].iov_base, Version);
1444 while (nfd--)
1445 close(fd[nfd]);
1446 while (niov--)
1447 free(iov[niov].iov_base);
1448 return;
1449 }
1450
1440 if (strncmp(Version, iov[0].iov_base, iov[0].iov_len)) {
1441 log_Printf(LogWARN, "Cannot receive datalink, incorrect version"
1442 " (\"%.*s\", not \"%s\")\n", (int)iov[0].iov_len,
1443 (char *)iov[0].iov_base, Version);
1444 while (nfd--)
1445 close(fd[nfd]);
1446 while (niov--)
1447 free(iov[niov].iov_base);
1448 return;
1449 }
1450
1451 /*
1452 * Everything looks good. Send the other side our process id so that
1453 * they can transfer lock ownership, and wait for them to send the
1454 * actual link data.
1455 */
1456 pid = getpid();
1457 if ((got = write(fd[1], &pid, sizeof pid)) != sizeof pid) {
1458 if (got == -1)
1459 log_Printf(LogERROR, "Failed write: %s\n", strerror(errno));
1460 else
1461 log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got,
1462 (int)(sizeof pid));
1463 while (nfd--)
1464 close(fd[nfd]);
1465 while (niov--)
1466 free(iov[niov].iov_base);
1467 return;
1468 }
1469
1470 if ((got = readv(fd[1], iov + 1, niov - 1)) != expect) {
1471 if (got == -1)
1472 log_Printf(LogERROR, "Failed write: %s\n", strerror(errno));
1473 else
1474 log_Printf(LogERROR, "Failed write: Got %d, not %d\n", got, expect);
1475 while (nfd--)
1476 close(fd[nfd]);
1477 while (niov--)
1478 free(iov[niov].iov_base);
1479 return;
1480 }
1481 close(fd[1]);
1482
1451 onfd = nfd; /* We've got this many in our array */
1452 nfd -= 2; /* Don't include p->fd and our reply descriptor */
1453 niov = 1; /* Skip the version id */
1454 dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, fd[0],
1455 fd + 2, &nfd);
1456 if (dl) {
1483 onfd = nfd; /* We've got this many in our array */
1484 nfd -= 2; /* Don't include p->fd and our reply descriptor */
1485 niov = 1; /* Skip the version id */
1486 dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, fd[0],
1487 fd + 2, &nfd);
1488 if (dl) {
1457 pid = getpid();
1458 write(fd[1], &pid, sizeof pid); /* Please hand me any locks */
1459 read(fd[1], &ack, 1); /* Thanks (ACK) ! */
1460 close(fd[1]);
1461
1462 if (nfd) {
1463 log_Printf(LogERROR, "bundle_ReceiveDatalink: Failed to handle %d "
1464 "auxiliary file descriptors (%d remain)\n", onfd, nfd);
1465 datalink_Destroy(dl);
1466 while (nfd--)
1467 close(fd[onfd--]);
1468 close(fd[0]);

--- 52 unchanged lines hidden (view full) ---

1521 */
1522 fd[1] = reply[1];
1523
1524 nfd += 2; /* Include fd[0] and fd[1] */
1525 memset(&msg, '\0', sizeof msg);
1526
1527 msg.msg_name = NULL;
1528 msg.msg_namelen = 0;
1489
1490 if (nfd) {
1491 log_Printf(LogERROR, "bundle_ReceiveDatalink: Failed to handle %d "
1492 "auxiliary file descriptors (%d remain)\n", onfd, nfd);
1493 datalink_Destroy(dl);
1494 while (nfd--)
1495 close(fd[onfd--]);
1496 close(fd[0]);

--- 52 unchanged lines hidden (view full) ---

1549 */
1550 fd[1] = reply[1];
1551
1552 nfd += 2; /* Include fd[0] and fd[1] */
1553 memset(&msg, '\0', sizeof msg);
1554
1555 msg.msg_name = NULL;
1556 msg.msg_namelen = 0;
1557 /*
1558 * Only send the version to start... We used to send the whole lot, but
1559 * this caused problems with our RECVBUF size as a single link is about
1560 * 22k ! This way, we should bump into no limits.
1561 */
1562 msg.msg_iovlen = 1;
1529 msg.msg_iov = iov;
1563 msg.msg_iov = iov;
1530 msg.msg_iovlen = niov;
1531 msg.msg_control = cmsgbuf;
1532 msg.msg_controllen = sizeof *cmsg + sizeof(int) * nfd;
1533 msg.msg_flags = 0;
1534
1535 cmsg = (struct cmsghdr *)cmsgbuf;
1536 cmsg->cmsg_len = msg.msg_controllen;
1537 cmsg->cmsg_level = SOL_SOCKET;
1538 cmsg->cmsg_type = SCM_RIGHTS;
1539
1540 for (f = 0; f < nfd; f++)
1541 *((int *)(cmsg + 1) + f) = fd[f];
1542
1564 msg.msg_control = cmsgbuf;
1565 msg.msg_controllen = sizeof *cmsg + sizeof(int) * nfd;
1566 msg.msg_flags = 0;
1567
1568 cmsg = (struct cmsghdr *)cmsgbuf;
1569 cmsg->cmsg_len = msg.msg_controllen;
1570 cmsg->cmsg_level = SOL_SOCKET;
1571 cmsg->cmsg_type = SCM_RIGHTS;
1572
1573 for (f = 0; f < nfd; f++)
1574 *((int *)(cmsg + 1) + f) = fd[f];
1575
1543 for (f = expect = 0; f < niov; f++)
1576 for (f = 1, expect = 0; f < niov; f++)
1544 expect += iov[f].iov_len;
1545
1577 expect += iov[f].iov_len;
1578
1579 if (setsockopt(reply[0], SOL_SOCKET, SO_SNDBUF, &expect, sizeof(int)) == -1)
1580 log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect,
1581 strerror(errno));
1582 if (setsockopt(reply[1], SOL_SOCKET, SO_RCVBUF, &expect, sizeof(int)) == -1)
1583 log_Printf(LogERROR, "setsockopt(SO_RCVBUF, %d): %s\n", expect,
1584 strerror(errno));
1585
1546 log_Printf(LogDEBUG, "Sending %d descriptor%s and %d bytes in scatter"
1586 log_Printf(LogDEBUG, "Sending %d descriptor%s and %d bytes in scatter"
1547 "/gather array\n", nfd, nfd == 1 ? "" : "s", expect);
1587 "/gather array\n", nfd, nfd == 1 ? "" : "s", iov[0].iov_len);
1548
1549 if ((got = sendmsg(s, &msg, 0)) == -1)
1550 log_Printf(LogERROR, "Failed sendmsg: %s: %s\n",
1551 sun->sun_path, strerror(errno));
1588
1589 if ((got = sendmsg(s, &msg, 0)) == -1)
1590 log_Printf(LogERROR, "Failed sendmsg: %s: %s\n",
1591 sun->sun_path, strerror(errno));
1552 else if (got != expect)
1553 log_Printf(LogERROR, "Failed sendmsg: %s: Only sent %d of %d\n",
1554 sun->sun_path, got, expect);
1592 else if (got != iov[0].iov_len)
1593 log_Printf(LogERROR, "%s: Failed initial sendmsg: Only sent %d of %d\n",
1594 sun->sun_path, got, iov[0].iov_len);
1555 else {
1556 /* We must get the ACK before closing the descriptor ! */
1557 int res;
1558
1595 else {
1596 /* We must get the ACK before closing the descriptor ! */
1597 int res;
1598
1559 read(reply[0], &newpid, sizeof newpid);
1560 log_Printf(LogDEBUG, "Received confirmation from pid %d\n", (int)newpid);
1561 if (lock && (res = ID0uu_lock_txfr(lock, newpid)) != UU_LOCK_OK)
1562 log_Printf(LogPHASE, "uu_lock_txfr: %s\n", uu_lockerr(res));
1599 if ((got = read(reply[0], &newpid, sizeof newpid)) == sizeof newpid) {
1600 log_Printf(LogDEBUG, "Received confirmation from pid %d\n",
1601 (int)newpid);
1602 if (lock && (res = ID0uu_lock_txfr(lock, newpid)) != UU_LOCK_OK)
1603 log_Printf(LogPHASE, "uu_lock_txfr: %s\n", uu_lockerr(res));
1563
1604
1564 write(reply[1], "!", 1); /* Thanks (ACK) ! */
1605 log_Printf(LogDEBUG, "Transmitting link (%d bytes)\n", expect);
1606 if ((got = writev(reply[0], iov + 1, niov - 1)) != expect) {
1607 if (got == -1)
1608 log_Printf(LogERROR, "%s: Failed writev: %s\n",
1609 sun->sun_path, strerror(errno));
1610 else
1611 log_Printf(LogERROR, "%s: Failed writev: Wrote %d of %d\n",
1612 sun->sun_path, got, expect);
1613 }
1614 } else if (got == -1)
1615 log_Printf(LogERROR, "%s: Failed socketpair read: %s\n",
1616 sun->sun_path, strerror(errno));
1617 else
1618 log_Printf(LogERROR, "%s: Failed socketpair read: Got %d of %d\n",
1619 sun->sun_path, got, (int)(sizeof newpid));
1565 }
1566
1567 close(reply[0]);
1568 close(reply[1]);
1569
1570 newsid = Enabled(dl->bundle, OPT_KEEPSESSION) ||
1571 tcgetpgrp(fd[0]) == getpgrp();
1572 while (nfd)

--- 304 unchanged lines hidden ---
1620 }
1621
1622 close(reply[0]);
1623 close(reply[1]);
1624
1625 newsid = Enabled(dl->bundle, OPT_KEEPSESSION) ||
1626 tcgetpgrp(fd[0]) == getpgrp();
1627 while (nfd)

--- 304 unchanged lines hidden ---