svc_vc.c (115394) | svc_vc.c (116391) |
---|---|
1/* $NetBSD: svc_vc.c,v 1.7 2000/08/03 00:01:53 fvdl Exp $ */ 2 3/* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or --- 20 unchanged lines hidden (view full) --- 29 * Mountain View, California 94043 30 */ 31 32#if defined(LIBC_SCCS) && !defined(lint) 33static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; 34static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC"; 35#endif 36#include <sys/cdefs.h> | 1/* $NetBSD: svc_vc.c,v 1.7 2000/08/03 00:01:53 fvdl Exp $ */ 2 3/* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or --- 20 unchanged lines hidden (view full) --- 29 * Mountain View, California 94043 30 */ 31 32#if defined(LIBC_SCCS) && !defined(lint) 33static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; 34static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC"; 35#endif 36#include <sys/cdefs.h> |
37__FBSDID("$FreeBSD: head/lib/libc/rpc/svc_vc.c 115394 2003-05-29 22:06:06Z mbr $"); | 37__FBSDID("$FreeBSD: head/lib/libc/rpc/svc_vc.c 116391 2003-06-15 10:32:01Z mbr $"); |
38 39/* 40 * svc_vc.c, Server side for Connection Oriented based RPC. 41 * 42 * Actually implements two flavors of transporter - 43 * a tcp rendezvouser (a listner and connection establisher) 44 * and a record/tcp stream. 45 */ --- 19 unchanged lines hidden (view full) --- 65#include <string.h> 66#include <unistd.h> 67 68#include <rpc/rpc.h> 69 70#include "rpc_com.h" 71#include "un-namespace.h" 72 | 38 39/* 40 * svc_vc.c, Server side for Connection Oriented based RPC. 41 * 42 * Actually implements two flavors of transporter - 43 * a tcp rendezvouser (a listner and connection establisher) 44 * and a record/tcp stream. 45 */ --- 19 unchanged lines hidden (view full) --- 65#include <string.h> 66#include <unistd.h> 67 68#include <rpc/rpc.h> 69 70#include "rpc_com.h" 71#include "un-namespace.h" 72 |
73struct cmessage { 74 struct cmsghdr cmsg; 75 struct cmsgcred cmcred; 76}; 77 | |
78extern rwlock_t svc_fd_lock; 79 80static SVCXPRT *makefd_xprt(int, u_int, u_int); 81static bool_t rendezvous_request(SVCXPRT *, struct rpc_msg *); 82static enum xprt_stat rendezvous_stat(SVCXPRT *); 83static void svc_vc_destroy(SVCXPRT *); 84static void __svc_vc_dodestroy (SVCXPRT *); 85static int read_vc(void *, void *, int); 86static int write_vc(void *, void *, int); 87static enum xprt_stat svc_vc_stat(SVCXPRT *); 88static bool_t svc_vc_recv(SVCXPRT *, struct rpc_msg *); 89static bool_t svc_vc_getargs(SVCXPRT *, xdrproc_t, void *); 90static bool_t svc_vc_freeargs(SVCXPRT *, xdrproc_t, void *); 91static bool_t svc_vc_reply(SVCXPRT *, struct rpc_msg *); 92static void svc_vc_rendezvous_ops(SVCXPRT *); 93static void svc_vc_ops(SVCXPRT *); 94static bool_t svc_vc_control(SVCXPRT *xprt, const u_int rq, void *in); 95static bool_t svc_vc_rendezvous_control (SVCXPRT *xprt, const u_int rq, 96 void *in); | 73extern rwlock_t svc_fd_lock; 74 75static SVCXPRT *makefd_xprt(int, u_int, u_int); 76static bool_t rendezvous_request(SVCXPRT *, struct rpc_msg *); 77static enum xprt_stat rendezvous_stat(SVCXPRT *); 78static void svc_vc_destroy(SVCXPRT *); 79static void __svc_vc_dodestroy (SVCXPRT *); 80static int read_vc(void *, void *, int); 81static int write_vc(void *, void *, int); 82static enum xprt_stat svc_vc_stat(SVCXPRT *); 83static bool_t svc_vc_recv(SVCXPRT *, struct rpc_msg *); 84static bool_t svc_vc_getargs(SVCXPRT *, xdrproc_t, void *); 85static bool_t svc_vc_freeargs(SVCXPRT *, xdrproc_t, void *); 86static bool_t svc_vc_reply(SVCXPRT *, struct rpc_msg *); 87static void svc_vc_rendezvous_ops(SVCXPRT *); 88static void svc_vc_ops(SVCXPRT *); 89static bool_t svc_vc_control(SVCXPRT *xprt, const u_int rq, void *in); 90static bool_t svc_vc_rendezvous_control (SVCXPRT *xprt, const u_int rq, 91 void *in); |
97static int __msgread_withcred(int, void *, size_t, struct cmessage *); | |
98static int __msgwrite(int, void *, size_t); 99 100struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */ 101 u_int sendsize; 102 u_int recvsize; 103 int maxrec; 104}; 105 --- 365 unchanged lines hidden (view full) --- 471 void *xprtp; 472 void *buf; 473 int len; 474{ 475 SVCXPRT *xprt; 476 int sock; 477 int milliseconds = 35 * 1000; 478 struct pollfd pollfd; | 92static int __msgwrite(int, void *, size_t); 93 94struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */ 95 u_int sendsize; 96 u_int recvsize; 97 int maxrec; 98}; 99 --- 365 unchanged lines hidden (view full) --- 465 void *xprtp; 466 void *buf; 467 int len; 468{ 469 SVCXPRT *xprt; 470 int sock; 471 int milliseconds = 35 * 1000; 472 struct pollfd pollfd; |
479 struct sockaddr *sa; 480 struct cmessage *cm; | |
481 struct cf_conn *cfp; 482 483 xprt = (SVCXPRT *)xprtp; 484 assert(xprt != NULL); 485 486 sock = xprt->xp_fd; 487 488 cfp = (struct cf_conn *)xprt->xp_p1; 489 | 473 struct cf_conn *cfp; 474 475 xprt = (SVCXPRT *)xprtp; 476 assert(xprt != NULL); 477 478 sock = xprt->xp_fd; 479 480 cfp = (struct cf_conn *)xprt->xp_p1; 481 |
490 cm = NULL; 491 sa = (struct sockaddr *)xprt->xp_rtaddr.buf; | |
492 if (cfp->nonblock) { | 482 if (cfp->nonblock) { |
493 if (sa->sa_family == AF_LOCAL) { 494 cm = (struct cmessage *)xprt->xp_verf.oa_base; 495 if ((len = __msgread_withcred(sock, buf, len, cm)) > 0) 496 xprt->xp_p2 = &cm->cmcred; 497 } else 498 len = _read(sock, buf, (size_t)len); | 483 len = _read(sock, buf, (size_t)len); |
499 if (len < 0) { 500 if (errno == EAGAIN) 501 len = 0; 502 else 503 goto fatal_err; 504 } 505 if (len != 0) 506 gettimeofday(&cfp->last_recv_time, NULL); --- 12 unchanged lines hidden (view full) --- 519 case 0: 520 goto fatal_err; 521 522 default: 523 break; 524 } 525 } while ((pollfd.revents & POLLIN) == 0); 526 | 484 if (len < 0) { 485 if (errno == EAGAIN) 486 len = 0; 487 else 488 goto fatal_err; 489 } 490 if (len != 0) 491 gettimeofday(&cfp->last_recv_time, NULL); --- 12 unchanged lines hidden (view full) --- 504 case 0: 505 goto fatal_err; 506 507 default: 508 break; 509 } 510 } while ((pollfd.revents & POLLIN) == 0); 511 |
527 if (sa->sa_family == AF_LOCAL) { 528 cm = (struct cmessage *)xprt->xp_verf.oa_base; 529 if ((len = __msgread_withcred(sock, buf, len, cm)) > 0) { 530 xprt->xp_p2 = &cm->cmcred; 531 return (len); 532 } else 533 goto fatal_err; 534 } else { 535 if ((len = _read(sock, buf, (size_t)len)) > 0) { 536 gettimeofday(&cfp->last_recv_time, NULL); 537 return (len); 538 } | 512 if ((len = _read(sock, buf, (size_t)len)) > 0) { 513 gettimeofday(&cfp->last_recv_time, NULL); 514 return (len); |
539 } 540 541fatal_err: 542 ((struct cf_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; 543 return (-1); 544} 545 546/* 547 * writes data to the tcp connection. 548 * Any error is fatal and the connection is closed. 549 */ 550static int 551write_vc(xprtp, buf, len) 552 void *xprtp; 553 void *buf; 554 int len; 555{ 556 SVCXPRT *xprt; 557 int i, cnt; | 515 } 516 517fatal_err: 518 ((struct cf_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; 519 return (-1); 520} 521 522/* 523 * writes data to the tcp connection. 524 * Any error is fatal and the connection is closed. 525 */ 526static int 527write_vc(xprtp, buf, len) 528 void *xprtp; 529 void *buf; 530 int len; 531{ 532 SVCXPRT *xprt; 533 int i, cnt; |
558 struct sockaddr *sa; | |
559 struct cf_conn *cd; 560 struct timeval tv0, tv1; 561 562 xprt = (SVCXPRT *)xprtp; 563 assert(xprt != NULL); 564 565 cd = (struct cf_conn *)xprt->xp_p1; 566 567 if (cd->nonblock) 568 gettimeofday(&tv0, NULL); 569 | 534 struct cf_conn *cd; 535 struct timeval tv0, tv1; 536 537 xprt = (SVCXPRT *)xprtp; 538 assert(xprt != NULL); 539 540 cd = (struct cf_conn *)xprt->xp_p1; 541 542 if (cd->nonblock) 543 gettimeofday(&tv0, NULL); 544 |
570 sa = (struct sockaddr *)xprt->xp_rtaddr.buf; | |
571 for (cnt = len; cnt > 0; cnt -= i, buf += i) { | 545 for (cnt = len; cnt > 0; cnt -= i, buf += i) { |
572 if (sa->sa_family == AF_LOCAL) 573 i = __msgwrite(xprt->xp_fd, buf, (size_t)cnt); 574 else 575 i = _write(xprt->xp_fd, buf, (size_t)cnt); | 546 i = _write(xprt->xp_fd, buf, (size_t)cnt); |
576 if (i < 0) { 577 if (errno != EAGAIN || !cd->nonblock) { 578 cd->strm_stat = XPRT_DIED; 579 return (-1); 580 } 581 if (cd->nonblock && i != cnt) { 582 /* 583 * For non-blocking connections, do not --- 158 unchanged lines hidden (view full) --- 742 ops.xp_destroy = svc_vc_destroy; 743 ops2.xp_control = svc_vc_rendezvous_control; 744 } 745 xprt->xp_ops = &ops; 746 xprt->xp_ops2 = &ops2; 747 mutex_unlock(&ops_lock); 748} 749 | 547 if (i < 0) { 548 if (errno != EAGAIN || !cd->nonblock) { 549 cd->strm_stat = XPRT_DIED; 550 return (-1); 551 } 552 if (cd->nonblock && i != cnt) { 553 /* 554 * For non-blocking connections, do not --- 158 unchanged lines hidden (view full) --- 713 ops.xp_destroy = svc_vc_destroy; 714 ops2.xp_control = svc_vc_rendezvous_control; 715 } 716 xprt->xp_ops = &ops; 717 xprt->xp_ops2 = &ops2; 718 mutex_unlock(&ops_lock); 719} 720 |
750int 751__msgread_withcred(sock, buf, cnt, cmp) 752 int sock; 753 void *buf; 754 size_t cnt; 755 struct cmessage *cmp; 756{ 757 struct iovec iov[1]; 758 struct msghdr msg; 759 union { 760 struct cmsghdr cmsg; 761 char control[CMSG_SPACE(sizeof(struct cmsgcred))]; 762 } cm; 763 int ret; 764 765 766 bzero(&cm, sizeof(cm)); 767 iov[0].iov_base = buf; 768 iov[0].iov_len = cnt; 769 770 msg.msg_iov = iov; 771 msg.msg_iovlen = 1; 772 msg.msg_name = NULL; 773 msg.msg_namelen = 0; 774 msg.msg_control = &cm; 775 msg.msg_controllen = CMSG_SPACE(sizeof(struct cmsgcred)); 776 msg.msg_flags = 0; 777 778 ret = _recvmsg(sock, &msg, 0); 779 bcopy(&cm.cmsg, &cmp->cmsg, sizeof(cmp->cmsg)); 780 bcopy(CMSG_DATA(&cm), &cmp->cmcred, sizeof(cmp->cmcred)); 781 782 if ((msg.msg_flags & MSG_CTRUNC) != 0) 783 return (-1); 784 785 return (ret); 786} 787 788static int 789__msgwrite(sock, buf, cnt) 790 int sock; 791 void *buf; 792 size_t cnt; 793{ 794 struct iovec iov[1]; 795 struct msghdr msg; 796 struct cmessage cm; 797 798 bzero((char *)&cm, sizeof(cm)); 799 iov[0].iov_base = buf; 800 iov[0].iov_len = cnt; 801 802 cm.cmsg.cmsg_type = SCM_CREDS; 803 cm.cmsg.cmsg_level = SOL_SOCKET; 804 cm.cmsg.cmsg_len = sizeof(struct cmessage); 805 806 msg.msg_iov = iov; 807 msg.msg_iovlen = 1; 808 msg.msg_name = NULL; 809 msg.msg_namelen = 0; 810 msg.msg_control = &cm; 811 msg.msg_controllen = sizeof(struct cmessage); 812 msg.msg_flags = 0; 813 814 return(_sendmsg(sock, &msg, 0)); 815} 816 | |
817/* | 721/* |
818 * Get the effective UID of the sending process. Used by rpcbind and keyserv 819 * (AF_LOCAL). | 722 * Get the effective UID of the sending process. Used by rpcbind, keyserv 723 * and rpc.yppasswdd on AF_LOCAL. |
820 */ 821int | 724 */ 725int |
822__rpc_get_local_uid(SVCXPRT *transp, uid_t *uid) 823{ 824 struct cmsgcred *cmcred; 825 struct cmessage *cm; 826 struct cmsghdr *cmp; 827 828 cm = (struct cmessage *)transp->xp_verf.oa_base; 829 830 if (cm == NULL) | 726__rpc_get_local_uid(SVCXPRT *transp, uid_t *uid) { 727 int sock, ret; 728 gid_t egid; 729 uid_t euid; 730 struct sockaddr *sa; 731 732 sock = transp->xp_fd; 733 sa = (struct sockaddr *)transp->xp_rtaddr.buf; 734 if (sa->sa_family == AF_LOCAL) { 735 ret = getpeereid(sock, &euid, &egid); 736 if (ret == 0) 737 *uid = euid; 738 return (ret); 739 } else |
831 return (-1); | 740 return (-1); |
832 cmp = &cm->cmsg; 833 if (cmp == NULL || cmp->cmsg_level != SOL_SOCKET || 834 cmp->cmsg_type != SCM_CREDS) 835 return (-1); 836 837 cmcred = __svc_getcallercreds(transp); 838 if (cmcred == NULL) 839 return (-1); 840 *uid = cmcred->cmcred_euid; 841 return (0); | |
842} 843 844/* 845 * Destroy xprts that have not have had any activity in 'timeout' seconds. 846 * If 'cleanblock' is true, blocking connections (the default) are also 847 * cleaned. If timeout is 0, the least active connection is picked. 848 */ 849bool_t --- 43 unchanged lines hidden --- | 741} 742 743/* 744 * Destroy xprts that have not have had any activity in 'timeout' seconds. 745 * If 'cleanblock' is true, blocking connections (the default) are also 746 * cleaned. If timeout is 0, the least active connection is picked. 747 */ 748bool_t --- 43 unchanged lines hidden --- |