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 --- |