130 lines
4.2 KiB
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);
|