Add a new clnt*_control CLSET_CONNECTED, which says the socket has already
authorderaadt <deraadt@openbsd.org>
Fri, 15 Jul 2022 17:33:28 +0000 (17:33 +0000)
committerderaadt <deraadt@openbsd.org>
Fri, 15 Jul 2022 17:33:28 +0000 (17:33 +0000)
been connected.  In the udp case, this means to use send(), not sendto()
ok jmatthew, claudio, miod

include/rpc/clnt.h
lib/libc/rpc/clnt_tcp.c
lib/libc/rpc/clnt_udp.c

index 3c21ef1..f7b3e54 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clnt.h,v 1.12 2022/02/14 03:38:59 guenther Exp $      */
+/*     $OpenBSD: clnt.h,v 1.13 2022/07/15 17:33:28 deraadt Exp $       */
 /*     $NetBSD: clnt.h,v 1.6 1995/04/29 05:27:58 cgd Exp $     */
 
 /*
@@ -214,6 +214,7 @@ typedef struct __rpc_client {
  */
 #define CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
 #define CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */
+#define CLSET_CONNECTED            6   /* socket is connected, so use send() */
 
 /*
  * void
index f1b4d9c..86675f8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clnt_tcp.c,v 1.35 2022/02/14 03:38:59 guenther Exp $ */
+/*     $OpenBSD: clnt_tcp.c,v 1.36 2022/07/15 17:33:28 deraadt Exp $ */
 
 /*
  * Copyright (c) 2010, Oracle America, Inc.
@@ -80,6 +80,7 @@ static const struct clnt_ops tcp_ops = {
 struct ct_data {
        int             ct_sock;
        bool_t          ct_closeit;
+       int             ct_connected;   /* pre-connected */
        struct timeval  ct_wait;
        bool_t          ct_waitset;       /* wait set by clnt_control? */
        struct sockaddr_in ct_addr; 
@@ -353,6 +354,9 @@ clnttcp_control(CLIENT *cl, u_int request, void *info)
        case CLGET_SERVER_ADDR:
                *(struct sockaddr_in *)info = ct->ct_addr;
                break;
+       case CLSET_CONNECTED:
+               ct->ct_connected = *(int *)info;
+               break;
        default:
                return (FALSE);
        }
index 56443a9..190d3ae 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clnt_udp.c,v 1.38 2022/02/14 03:38:59 guenther Exp $ */
+/*     $OpenBSD: clnt_udp.c,v 1.39 2022/07/15 17:33:28 deraadt Exp $ */
 
 /*
  * Copyright (c) 2010, Oracle America, Inc.
@@ -73,6 +73,7 @@ struct cu_data {
        int                cu_sock;
        bool_t             cu_closeit;
        struct sockaddr_in cu_raddr;
+       int                cu_connected;        /* use send() instead */
        int                cu_rlen;
        struct timeval     cu_wait;
        struct timeval     cu_total;
@@ -138,6 +139,7 @@ clntudp_bufcreate(struct sockaddr_in *raddr, u_long program, u_long version,
        cl->cl_ops = &udp_ops;
        cl->cl_private = (caddr_t)cu;
        cu->cu_raddr = *raddr;
+       cu->cu_connected = 0;
        cu->cu_rlen = sizeof (cu->cu_raddr);
        cu->cu_wait = wait;
        cu->cu_total.tv_sec = -1;
@@ -209,6 +211,7 @@ clntudp_call(CLIENT *cl,    /* client handle */
        XDR *xdrs;
        int outlen;
        int inlen;
+       int ret;
        socklen_t fromlen;
        struct pollfd pfd[1];
        struct sockaddr_in from;
@@ -244,8 +247,12 @@ call_again:
        outlen = (int)XDR_GETPOS(xdrs);
 
 send_again:
-       if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
-           (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {
+       if (cu->cu_connected)
+               ret = send(cu->cu_sock, cu->cu_outbuf, outlen, 0);
+       else
+               ret = sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
+                   (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen);
+       if (ret != outlen) {
                cu->cu_error.re_errno = errno;
                return (cu->cu_error.re_status = RPC_CANTSEND);
        }
@@ -411,6 +418,9 @@ clntudp_control(CLIENT *cl, u_int request, void *info)
        case CLGET_SERVER_ADDR:
                *(struct sockaddr_in *)info = cu->cu_raddr;
                break;
+       case CLSET_CONNECTED:
+               cu->cu_connected = *(int *)info;
+               break;
        default:
                return (FALSE);
        }