/* $arla: rx_globs.h,v 1.10 2003/01/19 08:49:58 lha Exp $ */ /* **************************************************************************** * Copyright IBM Corporation 1988, 1989 - All Rights Reserved * * * * Permission to use, copy, modify, and distribute this software and its * * documentation for any purpose and without fee is hereby granted, * * provided that the above copyright notice appear in all copies and * * that both that copyright notice and this permission notice appear in * * supporting documentation, and that the name of IBM not be used in * * advertising or publicity pertaining to distribution of the software * * without specific, written prior permission. * * * * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM * * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * **************************************************************************** */ /* RX: Globals for internal use, basically */ #ifdef KERNEL #include "../rx/rx.h" #else /* KERNEL */ #include "rx.h" #endif /* KERNEL */ #ifndef INIT #define INIT(x) #define EXT extern #endif /* INIT */ /* The array of installed services. Null terminated. */ EXT struct rx_service *rx_services[RX_MAX_SERVICES + 1]; /* Incoming calls wait on this queue when there are no available server processes */ EXT struct rx_queue rx_incomingCallQueue; /* Server processes wait on this queue when there are no appropriate calls to process */ EXT struct rx_queue rx_idleServerQueue; /* * Constant delay time before sending an acknowledge of the last * packet received. This is to avoid sending an extra acknowledge * when the client is about to make another call, anyway, or the * server is about to respond. */ EXT struct clock rx_lastAckDelay; #ifdef SOFT_ACK /* * Constant delay time before sending a hard ack if the receiver * consumes a packet while no delayed ack event is scheduled. Ensures * that the sender is able to advance its window when the receiver * consumes a packet after the sender has exhausted its transmit * window. */ EXT struct clock rx_hardAckDelay; /* * Constant delay time before sending a soft ack when none was * requested. This is to make sure we send soft acks before the * sender times out, Normally we wait and send a hard ack when the * receiver consumes the packet */ EXT struct clock rx_softAckDelay; #endif /* SOFT_ACK */ /* Variable to allow introduction of network unreliability */ #ifdef RXDEBUG EXT int rx_intentionallyDroppedPacketsPer100 INIT(0); /* Dropped on Send */ #endif EXT int rx_extraQuota INIT(0); /* extra packets to add to the quota */ EXT int rx_extraPackets INIT(32); /* extra packets to alloc (2 windows * by deflt) */ EXT int rx_stackSize INIT(RX_DEFAULT_STACK_SIZE); EXT int rx_connDeadTime INIT(12); /* Time until an unresponsive * connection is declared dead */ EXT int rx_idleConnectionTime INIT(700); /* Time until we toss an idle * connection */ EXT int rx_idlePeerTime INIT(60); /* Time until we toss a peer * structure, after all connections * using it have disappeared */ /* These definitions should be in one place */ #ifdef AFS_SUN5_ENV #define RX_CBUF_TIME 180 /* Check for cbuf deficit */ #define RX_REAP_TIME 90 /* Check for tossable connections * every 90 seconds */ #else #define RX_CBUF_TIME 120 /* Check for cbuf deficit */ #define RX_REAP_TIME 60 /* Check for tossable connections * every 60 seconds */ #endif #ifdef SOFT_ACK #define RX_FAST_ACK_RATE 1 EXT int rxi_SoftAckRate INIT(RX_FAST_ACK_RATE); EXT int rxi_HardAckRate INIT(RX_FAST_ACK_RATE + 1); #endif /* SOFT_ACK */ EXT int rx_Window INIT(15); /* Temporary HACK: transmit/receive * window */ EXT int rx_initialWindow INIT(2); /* "Slow start" with 2 packets */ EXT int rx_nPackets INIT(100); /* obsolete; use rx_extraPackets now */ /* List of free packets */ EXT struct rx_queue rx_freePacketQueue; EXT struct rx_queue rx_freeCbufQueue; #ifdef RX_ENABLE_LOCKS EXT afs_lock_t rx_freePktQ_lock; #endif /* Number of free packets */ EXT int rx_nFreePackets INIT(0); EXT int rx_nFreeCbufs INIT(0); EXT int rx_nCbufs INIT(0); EXT int rxi_NeedMoreCbufs INIT(0); EXT int rx_nWaiting INIT(0); /* largest packet which we can safely receive, initialized to AFS 3.2 value * This is provided for backward compatibility with peers which may be unable * to swallow anything larger. THIS MUST NEVER DECREASE WHILE AN APPLICATION * IS RUNNING! */ EXT u_long rx_maxReceiveSize INIT(OLD_MAX_PACKET_SIZE); EXT u_long rx_MyMaxSendSize INIT(OLD_MAX_PACKET_SIZE - RX_HEADER_SIZE); /* List of free queue entries */ EXT struct rx_serverQueueEntry *rx_FreeSQEList INIT(0); #ifdef RX_ENABLE_LOCKS EXT kmutex_t freeSQEList_lock; #endif /* List of free call structures */ EXT struct rx_queue rx_freeCallQueue; #ifdef RX_ENABLE_LOCKS EXT kmutex_t rx_freeCallQueue_lock; #endif EXT long rxi_nCalls INIT(0); /* Basic socket for client requests; other sockets (for receiving server requests) are in the service structures */ EXT osi_socket rx_socket; /* Port requested at rx_Init. If this is zero, the actual port used will be different--but it will only be used for client operations. If non-zero, server provided services may use the same port. */ EXT uint16_t rx_port; /* This is actually the minimum number of packets that must remain free, overall, immediately after a packet of the requested class has been allocated. *WARNING* These must be assigned with a great deal of care. In order, these are receive quota, send quota and special quota */ #define RX_PACKET_QUOTAS {1, 10, 0} /* value large enough to guarantee that no allocation fails due to RX_PACKET_QUOTAS. Make it a little bigger, just for fun */ #define RX_MAX_QUOTA 15 /* part of min packet computation */ EXT int rx_packetQuota[RX_N_PACKET_CLASSES] INIT(RX_PACKET_QUOTAS); EXT int rx_nextCid; /* Next connection call id */ EXT uint32_t rx_epoch; /* Initialization time of rx */ #ifdef RX_ENABLE_LOCKS EXT kmutex_t rx_waitingForPackets_lock; EXT kcondvar_t rx_waitingForPackets_cv; #endif EXT char rx_waitingForPackets; /* Processes set and wait on this * variable when waiting for packet * buffers */ EXT struct rx_stats rx_stats; EXT struct rx_peer **rx_peerHashTable; EXT struct rx_connection **rx_connHashTable; EXT u_long rx_hashTableSize INIT(256); /* Power of 2 */ EXT u_long rx_hashTableMask INIT(255); /* One less than rx_hashTableSize */ #define CONN_HASH(host, port, cid, epoch, type) ((((cid)>>RX_CIDSHIFT)&rx_hashTableMask)) #define PEER_HASH(host, port) ((host ^ port) & rx_hashTableMask) #ifdef notdef /* Use a func for now to measure * allocated structs */ #define rxi_Free(addr, size) osi_Free(addr, size) #endif /* notdef */ #define rxi_AllocSecurityObject() (struct rx_securityClass *) rxi_Alloc(sizeof(struct rx_securityClass)) #define rxi_FreeSecurityObject(obj) rxi_Free(obj, sizeof(struct rx_securityClass)) #define rxi_AllocService() (struct rx_service *) rxi_Alloc(sizeof(struct rx_service)) #define rxi_FreeService(obj) rxi_Free(obj, sizeof(struct rx_service)) #define rxi_AllocPeer() (struct rx_peer *) rxi_Alloc(sizeof(struct rx_peer)) #define rxi_FreePeer(peer) rxi_Free(peer, sizeof(struct rx_peer)) #define rxi_AllocConnection() (struct rx_connection *) rxi_Alloc(sizeof(struct rx_connection)) #define rxi_FreeConnection(conn) (rxi_Free(conn, sizeof(struct rx_connection))) /* Forward definitions of internal procedures */ struct rx_packet * rxi_AllocPacket(int); struct rx_packet * rxi_AllocSendPacket(struct rx_call *, int); void * rxi_Alloc(int); struct rx_peer * rxi_FindPeer(uint32_t, uint16_t); struct rx_call * rxi_NewCall(struct rx_connection *, int); void rxi_FreeCall(struct rx_call *); void rxi_Listener(void); int rxi_ReadPacket(int, struct rx_packet *, uint32_t *, uint16_t *); struct rx_packet * rxi_ReceivePacket(struct rx_packet *, osi_socket, uint32_t, uint16_t); struct rx_packet * rxi_ReceiveDataPacket(struct rx_call *, struct rx_packet *); struct rx_packet * rxi_ReceiveAckPacket(struct rx_call *, struct rx_packet *); struct rx_packet * rxi_ReceiveResponsePacket(struct rx_connection *, struct rx_packet *); struct rx_packet * rxi_ReceiveChallengePacket(struct rx_connection *, struct rx_packet *); void rx_ServerProc(void); void rxi_AttachServerProc(struct rx_call *); void rxi_ChallengeOn(struct rx_connection *); void rxi_InitPeerParams(struct rx_peer *); #define rxi_ChallengeOff(conn) rxevent_Cancel((conn)->challengeEvent); void rxi_ChallengeEvent(struct rxevent*, struct rx_connection *, char *); struct rx_packet *rxi_SendAck(struct rx_call *, struct rx_packet *, int, int, int, int); void rxi_ClearTransmitQueue(struct rx_call *); void rxi_ClearReceiveQueue(struct rx_call *); void rxi_ResetConnection(struct rx_connection *); void rxi_InitCall(void); /* obsolete ? */ void rxi_ResetCall(struct rx_call *); void rxi_CallError(struct rx_call *, int32_t); void rxi_ConnectionError(struct rx_connection *, int32_t); void rxi_QueuePackets(void); /* obsolete ? */ void rxi_Start(struct rxevent *, struct rx_call *); void rxi_CallIsIdle(void); /* obsolete ? */ void rxi_CallTimedOut(void); /* obsolete ? */ void rxi_ComputeRoundTripTime(struct rx_packet *, struct clock *, struct rx_peer *); void rxi_ScheduleKeepAliveEvent(struct rx_call *); void rxi_KeepAliveEvent(struct rxevent *, struct rx_call *, char *); void rxi_KeepAliveOn(struct rx_call *); #define rxi_KeepAliveOff(call) rxevent_Cancel((call)->keepAliveEvent) void rxi_AckAll(struct rxevent *, struct rx_call *, char *); void rxi_SendDelayedAck(struct rxevent *, struct rx_call *, char *); struct rx_packet *rxi_SendSpecial(struct rx_call *, struct rx_connection *, struct rx_packet *, int, char *, int); struct rx_packet *rxi_SendCallAbort(struct rx_call *, struct rx_packet *); struct rx_packet *rxi_SendConnectionAbort(struct rx_connection *, struct rx_packet *); void rxi_ScheduleDecongestionEvent(struct rx_call *, int); void rxi_CongestionWait(struct rx_call *); void rxi_ReapConnections(void); void rxi_EncodePacketHeader(struct rx_packet *); void rxi_DecodePacketHeader(struct rx_packet *); void rxi_DebugPrint(const char *, ...); void rxi_PrepareSendPacket(struct rx_call *, struct rx_packet *, int); void rxi_MoreCbufs(int); uint32_t rx_SlowGetLong(struct rx_packet *, int); void rxi_Send(struct rx_call *, struct rx_packet *); void rxi_FreeAllPackets(void); void rxi_SendPacket(struct rx_connection *, struct rx_packet *); int rxi_IsConnInteresting(struct rx_connection *); struct rx_packet *rxi_ReceiveDebugPacket(struct rx_packet *, osi_socket, uint32_t, uint16_t); struct rx_packet *rxi_ReceiveVersionPacket(struct rx_packet *, osi_socket, uint32_t, uint16_t); void rxi_SendDebugPacket(struct rx_packet *, osi_socket, uint32_t, uint16_t); #ifdef RXDEBUG /* Some debugging stuff */ EXT FILE *rx_debugFile; /* Set by the user to a stdio file for * debugging output */ #define Log rx_debugFile #define dpf(args) do { if (rx_debugFile) rxi_DebugPrint args; } while(0) EXT char *rx_packetTypes[RX_N_PACKET_TYPES] INIT(RX_PACKET_TYPES); /* Strings defined in * rx.h */ #else #define dpf(args) #endif /* RXDEBUG */