From 91fc4dda8d0d7cb149281baec1900502eccf803b Mon Sep 17 00:00:00 2001 From: deraadt Date: Fri, 15 Jul 2022 17:33:28 +0000 Subject: [PATCH] Add a new clnt*_control CLSET_CONNECTED, which says the socket has already been connected. In the udp case, this means to use send(), not sendto() ok jmatthew, claudio, miod --- include/rpc/clnt.h | 3 ++- lib/libc/rpc/clnt_tcp.c | 6 +++++- lib/libc/rpc/clnt_udp.c | 16 +++++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/rpc/clnt.h b/include/rpc/clnt.h index 3c21ef19bc1..f7b3e542c1b 100644 --- a/include/rpc/clnt.h +++ b/include/rpc/clnt.h @@ -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 diff --git a/lib/libc/rpc/clnt_tcp.c b/lib/libc/rpc/clnt_tcp.c index f1b4d9c0fcd..86675f8a505 100644 --- a/lib/libc/rpc/clnt_tcp.c +++ b/lib/libc/rpc/clnt_tcp.c @@ -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); } diff --git a/lib/libc/rpc/clnt_udp.c b/lib/libc/rpc/clnt_udp.c index 56443a932b4..190d3aeafc5 100644 --- a/lib/libc/rpc/clnt_udp.c +++ b/lib/libc/rpc/clnt_udp.c @@ -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); } -- 2.20.1