/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Portions of this source code were derived from Berkeley 4.3 BSD
* under license from the Regents of the University of California.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Boot subsystem client side rpc (TCP)
*/
#include "socket_inet.h"
#include "ipv4.h"
#include "clnt.h"
#include "brpc.h"
#include "pmap.h"
#include <rpc/auth_sys.h>
#include "auth_inet.h"
#include <sys/bootdebug.h>
extern int errno;
extern void xdrrec_create();
extern bool_t xdrrec_endofrecord();
extern bool_t xdrrec_skiprecord();
/*
* If we create another clnt type this should be
* moved to a common file
*/
static int readtcp();
static int writetcp();
static struct clnt_ops *clntbtcp_ops();
/*
* Private data kept per client handle
*/
struct ct_data {
int ct_sock;
};
/*
* Create a TCP based client handle.
* If *sockp<0, *sockp is set to a newly created TCP socket.
* If raddr->sin_port is 0 a binder on the remote machine
* is consulted for the correct port number.
* NB: It is the clients responsibility to close *sockp.
* 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; retransmition occurs until the actual
* rpc call times out.
*
* sendsz and recvsz are the maximum allowable packet sizes that can be
* sent and received.
*/
CLIENT *
struct sockaddr_in *raddr,
int *sockp,
{
#if 0 /* XXX not yet */
int min_buf_sz;
#endif /* not yet */
}
goto fooy;
}
goto fooy;
}
}
if (*sockp < 0) {
if (*sockp < 0) {
goto fooy;
}
/*
* Bootparams assumes a local net, so be sure to let lower
* layer protocols know not to route.
*/
if (dontroute) {
}
/* attempt to bind to priv port */
if (*sockp > 0)
goto fooy;
}
sizeof (struct sockaddr_in)) < 0) {
if (*sockp > 0)
goto fooy;
}
#if 0 /* XXX not yet */
/*
* In the future we may want RPC to use larger transfer sizes
* over TCP. In this case we will want to increase the
* window size.
*/
/*
* Resize the receive window if possible
*/
optlen = sizeof (int);
(void *)&min_buf_sz, &optlen) != 0)
goto keep_going;
if (min_buf_sz < pref_buf_sz)
(const void *)&pref_buf_sz, sizeof (int));
#endif /* not yet */
} else
/*
* Set up the private data
*/
ct->ct_wait_msec = 0;
/*
* Initialize the call message
*/
/*
* XXX - The xid might need to be randomized more. Imagine if there
* are a rack of blade servers all booting at the same time. They
* may cause havoc on the server with xid replays.
*/
/*
* pre-serialize the static part of the call msg and stash it away
*/
if (ct->ct_closeit)
goto fooy;
}
/*
* XXX - Memory allocations can fail in xdrrec_create, so we need to
* be able to catch those errors.
*/
writetcp);
return (cl);
fooy:
if (ct)
if (cl)
}
static enum clnt_stat
{
/*
* We have to be able to wait for some non-zero period of time, so
* use a default timeout.
*/
printf("clntbtcp_call: xdr encode args failed\n");
}
printf("clntbtcp_call: rpc cansend error\n");
}
if (!shipnow)
return (RPC_SUCCESS);
}
/* CONSTCOND */
while (TRUE) {
if (!xdrrec_skiprecord(xdrs)) {
}
continue;
}
break;
}
}
/*
* process header
*/
}
}
(void) xdr_opaque_auth(xdrs,
}
} else {
NULL)) {
goto call_again;
}
}
}
/*
* Interface between xdr serializer and tcp connection.
* Behaves like the system calls, read & write, but keeps some error state
* around for the rpc level.
*/
static int
int len)
{
int inlen = 0;
if (len <= 0)
return (0);
/*
* Do non-blocking reads here until we get some data or timeout
*/
start = prom_gettime();
&fromlen)) == 0) {
inlen = -1;
break;
}
}
#ifdef DEBUG
#endif
switch (inlen) {
case 0:
/* premature eof */
break;
case -1:
break;
}
return (inlen);
}
static int
int len;
{
register int i, cnt;
return (-1);
}
}
return (len);
}
static void
{
}
static bool_t
{
}
static void
/* CLIENT *h; */
{
}
/* ARGSUSED */
static bool_t
int request,
char *info)
{
/* Not implemented in boot */
return (FALSE);
}
static void
{
if (ct->ct_closeit) {
}
}
static struct clnt_ops *
{
}
return (&ops);
}