/*
 * jam 841031
 */

#include "../h/param.h"
#include "../h/mbuf.h"
#include "../h/socket.h"
#include "../net/if.h"
#include "../vnet/vnet.h"
#include "../conn/conn.h"
#include "../rpc/rpc.h"
#include "../s32/kstat.h"
#include "../rpc/rpc_stat.h"
#include "../h/errno.h"

extern struct ifnet *ifrpc;
extern int rpc_debug;

rpc_reply(pkt, conn, type)
   register rpc_header_t *pkt;
   connection_t *conn;
   u_short type;
{
	/* BUG should dump all but the first mbuf */
	pkt->source = myNode;
	pkt->sourcegen = myGeneration;
	pkt->type = type;
	pkt->version = RPC_VERSION;
	rpc_output(pkt, conn);
	rpc_freePkt(pkt);
}

rpc_replyError(pkt, conn, error)
   register rpc_header_t *pkt;
   connection_t *conn;
   int error;
{
	/* BUG should dump all but the first mbuf */
	pkt->source = myNode;
	pkt->sourcegen = myGeneration;
	pkt->type = RPCPKT_ERROR;
	pkt->version = RPC_VERSION;
	pkt->operation = error;
	rpc_output(pkt, conn);
	rpc_freePkt(pkt);
}

rpc_output(pkt, conn)
   rpc_header_t *pkt;
   connection_t *conn;
{
	rpc_sockaddr_t sockaddr;

	RPC_INCSTAT(outputs);
#ifdef	DEBUG
	if (rpc_debug)
		rpc_printdebug(pkt, 0);
#endif	DEBUG
	if (conn == NULL || conn->state != CONN_ACTIVE)
		return;
	sockaddr.addr_family = AF_RPC;
	sockaddr.node = conn->node;
	sockaddr.client = pkt->client;
	if (!ifrpc)
		return ENXIO;
	(*ifrpc->if_output)(ifrpc, m_copy(dtom(pkt), 0, M_COPYALL),
			    &sockaddr);
}

rpc_setRetryInfo(failrate, maxwait, maxretries, retryhz)
   int failrate;
   int maxwait;
   int *maxretries;
   int *retryhz;
{
	*maxretries = 5;
	if (*maxretries > 5)
		*retryhz = (maxwait*hz / (*maxretries - 5)) >> 5;
	else
		*retryhz = maxwait*hz >> *maxretries;
	if (*retryhz < hz/2)
		*retryhz = hz/2;
	while (*maxretries > 5 && *retryhz * (*maxretries-5) > maxwait*hz)
		--*maxretries;
	while (*retryhz << *maxretries > maxwait*hz)
		--*maxretries;
	if (*maxretries == 0)
		*maxretries = 1;
}
