src/lib/libc/rpc/clnt_udp_bufcreate.c

130 lines
4.2 KiB
C

/* $OpenBSD: clnt_udp_bufcreate.c,v 1.1 2024/01/22 16:18:06 deraadt Exp $ */
/*
* Copyright (c) 2010, Oracle America, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
* * Neither the name of the "Oracle America, Inc." nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* clnt_udp.c, Implements a UDP/IP based, client side RPC.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <rpc/pmap_clnt.h>
#include "clnt_udp.h"
/*
* Create a UDP based client handle.
* If *sockp<0, *sockp is set to a newly created UPD socket.
* If raddr->sin_port is 0 a binder on the remote machine
* is consulted for the correct port number.
* NB: It is the client's responsibility to close *sockp, unless
* clntudp_bufcreate() was called with *sockp = -1 (so it created
* the socket), and CLNT_DESTROY() is used.
* NB: The rpch->cl_auth is initialized to null authentication.
* Caller may wish to set this something more useful.
*
* wait is the amount of time used between retransmitting a call if
* no response has been heard; retransmission occurs until the actual
* rpc call times out.
*
* sendsz and recvsz are the maximum allowable packet sizes that can be
* sent and received.
*/
CLIENT *
clntudp_bufcreate(struct sockaddr_in *raddr, u_long program, u_long version,
struct timeval wait, int *sockp, u_int sendsz, u_int recvsz)
{
struct clntudp_bufcreate_args args;
args.raddr = raddr;
args.program = program;
args.version = version;
args.wait = wait;
args.sockp = sockp;
args.sendsz = sendsz;
args.recvsz = recvsz;
if (clntudp_bufcreate1(&args) == -1)
goto fooy;
if (raddr->sin_port == 0) {
u_short port;
if ((port =
pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
goto fooy;
}
raddr->sin_port = htons(port);
}
args.cu->cu_raddr = *raddr;
if (*sockp < 0) {
*sockp = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK,
IPPROTO_UDP);
if (*sockp == -1) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
/* attempt to bind to priv port */
(void)bindresvport(*sockp, NULL);
args.cu->cu_closeit = TRUE;
}
args.cu->cu_sock = *args.sockp;
if (clntudp_bufcreate2(&args) == -1)
goto fooy;
return (args.cl);
fooy:
if (args.cu)
mem_free((caddr_t)args.cu,
sizeof(*args.cu) + args.sendsz + args.recvsz);
if (args.cl)
mem_free((caddr_t)args.cl, sizeof(CLIENT));
return (NULL);
}
DEF_WEAK(clntudp_bufcreate);
CLIENT *
clntudp_create(struct sockaddr_in *raddr, u_long program, u_long version,
struct timeval wait, int *sockp)
{
return(clntudp_bufcreate(raddr, program, version, wait, sockp,
UDPMSGSIZE, UDPMSGSIZE));
}
DEF_WEAK(clntudp_create);