if (code && (code != UNOSERVERS)) {
server = 0;
if (conn && conn->conns[count - 1]
- && conn->conns[count - 1]->peer) {
- server = conn->conns[count - 1]->peer->host;
+ && rx_PeerOf(conn->conns[count - 1])) {
+ server = rx_PeerOf(conn->conns[count - 1])->host;
}
afs_com_err(whoami, code,
"so %s.%s may still be locked (on server %d.%d.%d.%d)",
return code;
}
code = ubik_EndTrans(tt);
- KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
+ KALOG(aname, ainstance, NULL, NULL, NULL, rx_PeerOf(call->conn)->host,
LOG_CRUSER);
return code;
}
goto abort;
code = ubik_EndTrans(tt);
- KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
+ KALOG(aname, ainstance, NULL, NULL, NULL, rx_PeerOf(call->conn)->host,
LOG_CHPASSWD);
return code;
DES_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, oanswer->SeqLen,
&user_schedule, ktc_to_cblockptr(&tentry.key), ENCRYPT);
code = ubik_EndTrans(tt);
- KALOG(aname, ainstance, sname, sinst, NULL, call->conn->peer->host,
+ KALOG(aname, ainstance, sname, sinst, NULL, rx_PeerOf(call->conn)->host,
LOG_AUTHENTICATE);
return code;
abort:
COUNT_ABO;
ubik_AbortTrans(tt);
- KALOG(aname, ainstance, sname, sinst, NULL, call->conn->peer->host,
+ KALOG(aname, ainstance, sname, sinst, NULL, rx_PeerOf(call->conn)->host,
LOG_AUTHFAILED);
return code;
}
goto abort;
code = ubik_EndTrans(tt);
- KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
+ KALOG(aname, ainstance, NULL, NULL, NULL, rx_PeerOf(call->conn)->host,
LOG_SETFIELDS);
return code;
goto abort;
code = ubik_EndTrans(tt);
- KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
+ KALOG(aname, ainstance, NULL, NULL, NULL, rx_PeerOf(call->conn)->host,
LOG_DELUSER);
return code;
}
&schedule, ktc_to_cblockptr(&authSessionKey), ENCRYPT);
code = ubik_EndTrans(tt);
KALOG(name, instance, sname, sinstance, (import ? authDomain : NULL),
- call->conn->peer->host, LOG_GETTICKET);
+ rx_PeerOf(call->conn)->host, LOG_GETTICKET);
return code;
abort:
kaux_write(to, 0, 0); /* zero failure counters at this offset */
code = ubik_EndTrans(tt);
- KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
+ KALOG(aname, ainstance, NULL, NULL, NULL, rx_PeerOf(call->conn)->host,
LOG_UNLOCK);
goto exit;
Kvice.cs.o \
fcrypt.o \
rx.o \
+ rx_conn.o \
rx_rdwr.o \
rx_clock.o \
rx_event.o \
xdr_int32.o \
xdr_int64.o \
rx.o \
+ rx_conn.o \
rx_rdwr.o \
rx_clock.o \
rx_event.o \
$(CRULE_NOOPT) $(TOP_SRC_VNOPS)/afs_vnop_write.c
afs_volume.o: $(TOP_SRC_AFS)/afs_volume.c
$(CRULE_OPT) $(TOP_SRC_AFS)/afs_volume.c
+rx_conn.o: $(TOP_SRC_RX)/rx_conn.c
+ $(CRULE_OPT) $(TOP_SRC_RX)/rx_conn.c
rx_rdwr.o: $(TOP_SRC_RX)/rx_rdwr.c
$(CRULE_OPT) $(TOP_SRC_RX)/rx_rdwr.c
afs_uuid.o: $(TOP_SRCDIR)/util/uuid.c
rx.o \
rx_null.o \
rx_opaque.o \
+ rx_conn.o \
rx_conncache.o \
rx_globals.o \
rx_identity.o \
rx_conncache.o: ${RX}/rx_conncache.c
$(AFS_CCRULE) $(RX)/rx_conncache.c
+rx_conn.o: ${RX}/rx_conn.c
+ $(AFS_CCRULE) $(RX)/rx_conn.c
+
rx_null.o: ${RX}/rx_null.c
$(AFS_CCRULE) $(RX)/rx_null.c
$(OUT)\rx_globals.obj $(OUT)\rx_getaddr.obj $(OUT)\rx_misc.obj \
$(OUT)\rx_packet.obj $(OUT)\rx_rdwr.obj $(OUT)\rx_trace.obj \
$(OUT)\rx_xmit_nt.obj $(OUT)\rx_conncache.obj $(OUT)\rx_opaque.obj \
- $(OUT)\rx_identity.obj $(OUT)\rx_stats.obj
+ $(OUT)\rx_identity.obj $(OUT)\rx_stats.obj \
+ $(OUT)\rx_conn.obj
RXSTATBJS = $(OUT)\rxstat.obj $(OUT)\rxstat.ss.obj $(OUT)\rxstat.xdr.obj $(OUT)\rxstat.cs.obj
rx_GetThreadNum @305
rx_SetThreadNum @306
+ rx_SetConnectionEpoch @307
+ rx_GetConnectionEpoch @308
+ rx_SetConnectionId @309
+ rx_GetConnectionId @310
+ rx_GetSecurityData @311
+ rx_SetSecurityData @312
+ rx_IsUsingPktCksum @313
+ rx_SetSecurityHeaderSize @314
+ rx_GetSecurityHeaderSize @315
+ rx_SetSecurityMaxTrailerSize @316
+ rx_GetSecurityMaxTrailerSize @317
+ rx_SetServerConnIdleDeadErr @318
+ rx_SetMsgsizeRetryErr @319
+ rx_IsServerConn @320
+ rx_IsClientConn @321
+ rx_SecurityObjectOf @322
+ rx_PeerOf @323
+ rx_ServiceIdOf @324
+ rx_SecurityClassOf @325
+ rx_ServiceOf @326
+ rx_ConnError @327
+
; for performance testing
rx_TSFPQGlobSize @2001 DATA
rx_TSFPQLocalMax @2002 DATA
$(UOBJ)/rx_stats.o \
$(UOBJ)/rx_packet.o \
$(UOBJ)/rx_conncache.o \
+ $(UOBJ)/rx_conn.o \
$(UOBJ)/xdr_rx.o \
$(UOBJ)/Kvldbint.cs.o \
$(UOBJ)/Kvldbint.xdr.o \
$(PICOBJ)/rx_stats.o \
$(PICOBJ)/rx_packet.o \
$(PICOBJ)/rx_conncache.o \
+ $(PICOBJ)/rx_conn.o \
$(PICOBJ)/xdr_rx.o \
$(PICOBJ)/Kvldbint.cs.o \
$(PICOBJ)/Kvldbint.xdr.o \
$(WEBOBJ)/rx_stats.o \
$(WEBOBJ)/rx_packet.o \
$(WEBOBJ)/rx_conncache.o \
+ $(WEBOBJ)/rx_conn.o \
$(WEBOBJ)/xdr_rx.o \
$(WEBOBJ)/Kvldbint.cs.o \
$(WEBOBJ)/Kvldbint.xdr.o \
$(WEBOBJ)/rx_stats.o \
$(WEBOBJ)/rx_packet.o \
$(WEBOBJ)/rx_conncache.o \
+ $(WEBOBJ)/rx_conn.o \
$(WEBOBJ)/xdr_rx.o \
$(WEBOBJ)/Kvldbint.cs.o \
$(WEBOBJ)/Kvldbint.xdr.o \
$(JUAFS)/rx_stats.o \
$(JUAFS)/rx_packet.o \
$(JUAFS)/rx_conncache.o \
+ $(JUAFS)/rx_conn.o \
$(JUAFS)/xdr_rx.o \
$(JUAFS)/Kvldbint.cs.o \
$(JUAFS)/Kvldbint.xdr.o \
$(CRULE1)
$(UOBJ)/rx_conncache.o: $(TOP_SRCDIR)/rx/rx_conncache.c
$(CRULE1)
+$(UOBJ)/rx_conn.o: $(TOP_SRCDIR)/rx/rx_conn.c
+ $(CRULE1)
$(UOBJ)/xdr_rx.o: $(TOP_SRC_RX)/xdr_rx.c
$(CRULE1)
$(UOBJ)/xdr_int32.o: $(TOP_SRC_RX)/xdr_int32.c
$(CRULEPIC)
$(PICOBJ)/rx_conncache.o: $(TOP_SRCDIR)/rx/rx_conncache.c
$(CRULEPIC)
+$(PICOBJ)/rx_conn.o: $(TOP_SRCDIR)/rx/rx_conn.c
+ $(CRULEPIC)
$(PICOBJ)/xdr_rx.o: $(TOP_SRC_RX)/xdr_rx.c
$(CRULEPIC)
$(PICOBJ)/xdr_int32.o: $(TOP_SRC_RX)/xdr_int32.c
$(CRULE2)
$(WEBOBJ)/rx_conncache.o: $(TOP_SRCDIR)/rx/rx_conncache.c
$(CRULE2)
+$(WEBOBJ)/rx_conn.o: $(TOP_SRCDIR)/rx/rx_conn.c
+ $(CRULE2)
$(WEBOBJ)/xdr_rx.o: $(TOP_SRC_RX)/xdr_rx.c
$(CRULE2)
$(WEBOBJ)/afs_usrops.o: $(TOP_SRC_AFS)/UKERNEL/afs_usrops.c
$(CRULE1)
$(JUAFS)/rx_conncache.o: $(TOP_SRCDIR)/rx/rx_conncache.c
$(CRULE1)
+$(JUAFS)/rx_conn.o: $(TOP_SRC_RX)/rx_conn.c
+ $(CRULE1)
$(JUAFS)/xdr_rx.o: $(TOP_SRC_RX)/xdr_rx.c
$(CRULE1)
$(JUAFS)/xdr_int64.o: $(TOP_SRC_RX)/xdr_int64.c
XDROBJS = xdr_arrayn.o ${XDROBJS_common}
-RXOBJS_common = rx_clock.o rx_event.o rx_user.o rx_lwp.o rx.o rx_null.o \
+RXOBJS_common = rx_clock.o rx_conn.o rx_event.o rx_user.o rx_lwp.o rx.o rx_null.o \
rx_globals.o rx_getaddr.o rx_misc.o rx_packet.o rx_rdwr.o rx_trace.o \
rx_conncache.o rx_opaque.o rx_identity.o rx_stats.o \
xdr_int32.o xdr_int64.o xdr_update.o xdr_refernce.o
$(OUT)\rx_globals.obj $(OUT)\rx_getaddr.obj $(OUT)\rx_misc.obj \
$(OUT)\rx_packet.obj $(OUT)\rx_rdwr.obj $(OUT)\rx_trace.obj \
$(OUT)\rx_xmit_nt.obj $(OUT)\rx_conncache.obj \
- $(OUT)\rx_opaque.obj $(OUT)\rx_identity.obj $(OUT)\rx_stats.obj
+ $(OUT)\rx_opaque.obj $(OUT)\rx_identity.obj $(OUT)\rx_stats.obj \
+ $(OUT)\rx_conn.obj
MULTIOBJS = $(OUT)\rx_multi.obj
#include "rx_stats.h"
#include "rx_event.h"
+#include "rx_conn.h"
+
#include <afs/rxgen_consts.h>
#ifndef KERNEL
#include "rx_null.h"
#include "rx_multi.h"
+/* These items are part of the new RX API. They're living in this section
+ * for now, to keep them separate from everything else... */
+
+/* Connection management */
+struct rx_connection;
+
+extern void rx_SetConnectionEpoch(struct rx_connection *conn, int epoch);
+extern int rx_GetConnectionEpoch(struct rx_connection *conn);
+extern void rx_SetConnectionId(struct rx_connection *conn, int id);
+extern int rx_GetConnectionId(struct rx_connection *conn);
+extern void *rx_GetSecurityData(struct rx_connection *conn);
+extern void rx_SetSecurityData(struct rx_connection *conn, void *data);
+extern int rx_IsUsingPktCksum(struct rx_connection *conn);
+extern void rx_SetSecurityHeaderSize(struct rx_connection *conn, int size);
+extern int rx_GetSecurityHeaderSize(struct rx_connection *conn);
+extern void rx_SetSecurityMaxTrailerSize(struct rx_connection *conn, int size);
+extern int rx_GetSecurityMaxTrailerSize(struct rx_connection *conn);
+extern void rx_SetServerConnIdleDeadErr(struct rx_connection *conn, int err);
+extern void rx_SetMsgsizeRetryErr(struct rx_connection *conn, int err);
+extern int rx_IsServerConn(struct rx_connection *conn);
+extern int rx_IsClientConn(struct rx_connection *conn);
+extern struct rx_securityClass *rx_SecurityObjectOf(const struct rx_connection *);
+extern struct rx_peer *rx_PeerOf(struct rx_connection *);
+extern u_short rx_ServiceIdOf(struct rx_connection *);
+extern int rx_SecurityClassOf(struct rx_connection *);
+extern struct rx_service *rx_ServiceOf(struct rx_connection *);
+extern int rx_ConnError(struct rx_connection *);
+
/* Configurable parameters */
#define RX_IDLE_DEAD_TIME 60 /* default idle dead time */
#define RX_MAX_SERVICES 20 /* Maximum number of services that may be installed */
#define RX_DONTWAIT 0
#define rx_ConnectionOf(call) ((call)->conn)
-#define rx_PeerOf(conn) ((conn)->peer)
#define rx_HostOf(peer) ((peer)->host)
#define rx_PortOf(peer) ((peer)->port)
#define rx_SetLocalStatus(call, status) ((call)->localStatus = (status))
#define rx_GetLocalStatus(call, status) ((call)->localStatus)
#define rx_GetRemoteStatus(call) ((call)->remoteStatus)
#define rx_Error(call) ((call)->error)
-#define rx_ConnError(conn) ((conn)->error)
-#define rx_IsServerConn(conn) ((conn)->type == RX_SERVER_CONNECTION)
-#define rx_IsClientConn(conn) ((conn)->type == RX_CLIENT_CONNECTION)
-/* Don't use these; use the IsServerConn style */
-#define rx_ServerConn(conn) ((conn)->type == RX_SERVER_CONNECTION)
-#define rx_ClientConn(conn) ((conn)->type == RX_CLIENT_CONNECTION)
-#define rx_IsUsingPktCksum(conn) ((conn)->flags & RX_CONN_USING_PACKET_CKSUM)
-#define rx_ServiceIdOf(conn) ((conn)->serviceId)
-#define rx_SecurityClassOf(conn) ((conn)->securityIndex)
-#define rx_SecurityObjectOf(conn) ((conn)->securityObject)
static_inline int
rx_IsLoopbackAddr(afs_uint32 addr)
/* Enable or disable asymmetric client checking for a service */
#define rx_SetCheckReach(service, x) ((service)->checkReach = (x))
-#define rx_SetServerConnIdleDeadErr(conn,err) ((conn)->idleDeadErr = (err))
/* Set the overload threshold and the overload error */
#define rx_SetBusyThreshold(threshold, code) (rx_BusyThreshold=(threshold),rx_BusyError=(code))
-/* Set the error to use for retrying a connection during MTU tuning */
-#define rx_SetMsgsizeRetryErr(conn, err) ((conn)->msgsizeRetryErr = (err))
-
/* If this flag is set,no new requests are processed by rx, all new requests are
returned with an error code of RX_CALL_DEAD ( transient error ) */
#define rx_SetRxTranquil() (rx_tranquil = 1)
#define rx_PutConnection(conn) rx_DestroyConnection(conn)
-/* A connection is an authenticated communication path, allowing
- limited multiple asynchronous conversations. */
-#ifdef KDUMP_RX_LOCK
-struct rx_connection_rx_lock {
- struct rx_connection_rx_lock *next; /* on hash chain _or_ free list */
- struct rx_peer_rx_lock *peer;
-#else
-struct rx_connection {
- struct rx_connection *next; /* on hash chain _or_ free list */
- struct rx_peer *peer;
-#endif
-#ifdef RX_ENABLE_LOCKS
- afs_kmutex_t conn_call_lock; /* locks conn_call_cv */
- afs_kcondvar_t conn_call_cv;
- afs_kmutex_t conn_data_lock; /* locks packet data */
-#endif
- afs_uint32 epoch; /* Process start time of client side of connection */
- afs_uint32 cid; /* Connection id (call channel is bottom bits) */
- afs_int32 error; /* If this connection is in error, this is it */
-#ifdef KDUMP_RX_LOCK
- struct rx_call_rx_lock *call[RX_MAXCALLS];
-#else
- struct rx_call *call[RX_MAXCALLS];
-#endif
- afs_uint32 callNumber[RX_MAXCALLS]; /* Current call numbers */
- afs_uint32 rwind[RX_MAXCALLS];
- u_short twind[RX_MAXCALLS];
- afs_uint32 lastBusy[RX_MAXCALLS]; /* timestamp of the last time we got an
- * RX_PACKET_TYPE_BUSY packet for this
- * call slot, or 0 if the slot is not busy */
- afs_uint32 serial; /* Next outgoing packet serial number */
- afs_uint32 lastSerial; /* # of last packet received, for computing skew */
- afs_int32 lastPacketSize; /* last >max attempt */
- afs_int32 lastPacketSizeSeq; /* seq number of attempt */
- afs_int32 lastPingSize; /* last MTU ping attempt */
- afs_int32 lastPingSizeSer; /* serial of last MTU ping attempt */
- struct rxevent *challengeEvent; /* Scheduled when the server is challenging a */
- struct rxevent *delayedAbortEvent; /* Scheduled to throttle looping client */
- struct rxevent *checkReachEvent; /* Scheduled when checking reachability */
- int abortCount; /* count of abort messages sent */
- /* client-- to retransmit the challenge */
- struct rx_service *service; /* used by servers only */
- u_short serviceId; /* To stamp on requests (clients only) */
- afs_int32 refCount; /* Reference count (rx_refcnt_mutex) */
- u_char flags; /* Defined below - (conn_data_lock) */
- u_char type; /* Type of connection, defined below */
- u_char secondsUntilPing; /* how often to ping for each active call */
- u_char securityIndex; /* corresponds to the security class of the */
- /* securityObject for this conn */
- struct rx_securityClass *securityObject; /* Security object for this connection */
- void *securityData; /* Private data for this conn's security class */
- u_short securityHeaderSize; /* Length of security module's packet header data */
- u_short securityMaxTrailerSize; /* Length of security module's packet trailer data */
-
- int timeout; /* Overall timeout per call (seconds) for this conn */
- int lastSendTime; /* Last send time for this connection */
- u_short secondsUntilDead; /* Maximum silence from peer before RX_CALL_DEAD */
- u_short hardDeadTime; /* hard max for call execution */
- u_short idleDeadTime; /* max time a call can be idle (no data) */
- u_char ackRate; /* how many packets between ack requests */
- u_char makeCallWaiters; /* how many rx_NewCalls are waiting */
- afs_int32 idleDeadErr;
- afs_int32 secondsUntilNatPing; /* how often to ping conn */
- struct rxevent *natKeepAliveEvent; /* Scheduled to keep connection open */
- afs_int32 msgsizeRetryErr;
- int nSpecific; /* number entries in specific data */
- void **specific; /* pointer to connection specific data */
-};
-
-
/* A service is installed by rx_NewService, and specifies a service type that
* is exported by this process. Incoming calls are stamped with the service
* type, and must match an installed service for the call to be accepted.
--- /dev/null
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * Copyright 2011, Your File System Inc
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License. For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+#include <afsconfig.h>
+#include <afs/param.h>
+
+#include <roken.h>
+
+#include "rx.h"
+#include "rx_conn.h"
+
+void
+rx_SetConnectionEpoch(struct rx_connection *conn, afs_int32 epoch) {
+ conn->epoch = epoch;
+}
+
+int
+rx_GetConnectionEpoch(struct rx_connection *conn) {
+ return conn->epoch;
+}
+
+void
+rx_SetConnectionId(struct rx_connection *conn, int cid) {
+ conn->cid = cid;
+}
+
+int
+rx_GetConnectionId(struct rx_connection *conn) {
+ return conn->cid;
+}
+
+void
+rx_SetSecurityData(struct rx_connection *conn, void *data) {
+ conn->securityData = data;
+}
+
+void *
+rx_GetSecurityData(struct rx_connection *conn)
+{
+ return conn->securityData;
+}
+
+int
+rx_IsUsingPktCksum(struct rx_connection *conn)
+{
+ return conn->flags & RX_CONN_USING_PACKET_CKSUM;
+}
+
+void
+rx_SetSecurityHeaderSize(struct rx_connection *conn, int size)
+{
+ conn->securityHeaderSize = size;
+}
+
+int
+rx_GetSecurityHeaderSize(struct rx_connection *conn)
+{
+ return conn->securityHeaderSize;
+}
+
+void
+rx_SetSecurityMaxTrailerSize(struct rx_connection *conn, int size)
+{
+ conn->securityMaxTrailerSize = size;
+}
+
+int
+rx_GetSecurityMaxTrailerSize(struct rx_connection *conn)
+{
+ return conn->securityMaxTrailerSize;
+}
+
+void
+rx_SetServerConnIdleDeadErr(struct rx_connection *conn, int err)
+{
+ conn->idleDeadErr = err;
+}
+
+void
+rx_SetMsgsizeRetryErr(struct rx_connection *conn, int err)
+{
+ conn->msgsizeRetryErr = err;
+}
+
+int
+rx_IsServerConn(struct rx_connection *conn)
+{
+ return conn->type == RX_SERVER_CONNECTION;
+}
+
+int
+rx_IsClientConn(struct rx_connection *conn)
+{
+ return conn->type == RX_CLIENT_CONNECTION;
+}
+
+struct rx_peer *
+rx_PeerOf(struct rx_connection *conn)
+{
+ return conn->peer;
+}
+
+u_short
+rx_ServiceIdOf(struct rx_connection *conn)
+{
+ return conn->serviceId;
+}
+
+int
+rx_SecurityClassOf(struct rx_connection *conn)
+{
+ return conn->securityIndex;
+}
+
+struct rx_securityClass *
+rx_SecurityObjectOf(const struct rx_connection *conn)
+{
+ return conn->securityObject;
+}
+
+struct rx_service *
+rx_ServiceOf(struct rx_connection *conn)
+{
+ return conn->service;
+}
+
+int
+rx_ConnError(struct rx_connection *conn)
+{
+ return conn->error;
+}
--- /dev/null
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License. For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+#ifndef OPENAFS_RX_CONN_H
+#define OPENAFS_RX_CONN_H 1
+
+/* A connection is an authenticated communication path, allowing limited
+ * multiple asynchronous conversations. */
+
+#ifdef KDUMP_RX_LOCK
+struct rx_connection_rx_lock {
+ struct rx_connection_rx_lock *next; /* on hash chain _or_ free list */
+ struct rx_peer_rx_lock *peer;
+#else
+struct rx_connection {
+ struct rx_connection *next; /* on hash chain _or_ free list */
+ struct rx_peer *peer;
+#endif
+#ifdef RX_ENABLE_LOCKS
+ afs_kmutex_t conn_call_lock; /* locks conn_call_cv */
+ afs_kcondvar_t conn_call_cv;
+ afs_kmutex_t conn_data_lock; /* locks packet data */
+#endif
+ afs_uint32 epoch; /* Process start time of client side of connection */
+ afs_uint32 cid; /* Connection id (call channel is bottom bits) */
+ afs_int32 error; /* If this connection is in error, this is it */
+#ifdef KDUMP_RX_LOCK
+ struct rx_call_rx_lock *call[RX_MAXCALLS];
+#else
+ struct rx_call *call[RX_MAXCALLS];
+#endif
+ afs_uint32 callNumber[RX_MAXCALLS]; /* Current call numbers */
+ afs_uint32 rwind[RX_MAXCALLS];
+ u_short twind[RX_MAXCALLS];
+ afs_uint32 lastBusy[RX_MAXCALLS]; /* timestamp of the last time we got an
+ * RX_PACKET_TYPE_BUSY packet for this
+ * call slot, or 0 if the slot is not busy */
+ afs_uint32 serial; /* Next outgoing packet serial number */
+ afs_uint32 lastSerial; /* # of last packet received, for computing skew */
+ afs_int32 lastPacketSize; /* last >max attempt */
+ afs_int32 lastPacketSizeSeq; /* seq number of attempt */
+ afs_int32 lastPingSize; /* last MTU ping attempt */
+ afs_int32 lastPingSizeSer; /* serial of last MTU ping attempt */
+ struct rxevent *challengeEvent; /* Scheduled when the server is challenging a */
+ struct rxevent *delayedAbortEvent; /* Scheduled to throttle looping client */
+ struct rxevent *checkReachEvent; /* Scheduled when checking reachability */
+ int abortCount; /* count of abort messages sent */
+ /* client-- to retransmit the challenge */
+ struct rx_service *service; /* used by servers only */
+ u_short serviceId; /* To stamp on requests (clients only) */
+ afs_int32 refCount; /* Reference count (rx_refcnt_mutex) */
+ u_char flags; /* Defined below - (conn_data_lock) */
+ u_char type; /* Type of connection, defined below */
+ u_char secondsUntilPing; /* how often to ping for each active call */
+ u_char securityIndex; /* corresponds to the security class of the */
+ /* securityObject for this conn */
+ struct rx_securityClass *securityObject; /* Security object for this connection */
+ void *securityData; /* Private data for this conn's security class */
+ u_short securityHeaderSize; /* Length of security module's packet header data */
+ u_short securityMaxTrailerSize; /* Length of security module's packet trailer data */
+
+ int timeout; /* Overall timeout per call (seconds) for this conn */
+ int lastSendTime; /* Last send time for this connection */
+ u_short secondsUntilDead; /* Maximum silence from peer before RX_CALL_DEAD */
+ u_short hardDeadTime; /* hard max for call execution */
+ u_short idleDeadTime; /* max time a call can be idle (no data) */
+ u_char ackRate; /* how many packets between ack requests */
+ u_char makeCallWaiters; /* how many rx_NewCalls are waiting */
+ afs_int32 idleDeadErr;
+ afs_int32 secondsUntilNatPing; /* how often to ping conn */
+ struct rxevent *natKeepAliveEvent; /* Scheduled to keep connection open */
+ afs_int32 msgsizeRetryErr;
+ int nSpecific; /* number entries in specific data */
+ void **specific; /* pointer to connection specific data */
+};
+
+#endif
+
#include "rx.h"
+#include "rx_conn.h"
+
/*
* We initialize rxi_connectionCache at compile time, so there is no
* need to call queue_Init(&rxi_connectionCache).
#include "rx_internal.h"
#include "rx_stats.h"
+#include "rx_conn.h"
+
#ifdef RX_LOCKS_DB
/* rxdb_fileID is used to identify the lock location, along with line#. */
static int rxdb_fileID = RXDB_FILE_RX_PACKET;
((struct rx_packet *) \
((char *)(CP) - ((char *)(&(PP)->localdata[0])-(char *)(PP))))
-/* Macros callable by security modules, to set header/trailer lengths,
- * set actual packet size, and find the beginning of the security
- * header (or data) */
-#define rx_SetSecurityHeaderSize(conn, length) ((conn)->securityHeaderSize = (length))
-#define rx_SetSecurityMaxTrailerSize(conn, length) ((conn)->securityMaxTrailerSize = (length))
-#define rx_GetSecurityHeaderSize(conn) ((conn)->securityHeaderSize)
-#define rx_GetSecurityMaxTrailerSize(conn) ((conn)->securityMaxTrailerSize)
-
/* This is the address of the data portion of the packet. Any encryption
* headers will be at this address, the actual data, for a data packet, will
* start at this address + the connection's security header size. */
#include "rx_queue.h"
#include "rx_globals.h"
+#include "rx_conn.h"
+
#ifdef RX_LOCKS_DB
/* rxdb_fileID is used to identify the lock location, along with line#. */
static int rxdb_fileID = RXDB_FILE_RX_RDWR;
#include "rx_internal.h"
#include "rx_trace.h"
+#include "rx_conn.h"
+
#ifdef RXTRACEON
char rxi_tracename[80] = "/tmp/rxcalltrace";
#else
if (dumpstats) {
rx_PrintStats(stdout);
- rx_PrintPeerStats(stdout, conn->peer);
+ rx_PrintPeerStats(stdout, rx_PeerOf(conn));
}
rx_Finalize();
int logstdout = 0;
struct rx_connection *conn;
struct rx_call *call;
+ struct rx_peer *peer;
int err = 0;
int nCalls = 1, nBytes = 1;
int bufferSize = 4000000;
Abort("unable to make a new connection");
/* Set initial parameters. This is (currently) not the approved interface */
+ peer = rx_PeerOf(conn);
if (burst)
- conn->peer->burstSize = conn->peer->burst = burst;
+ peer->burstSize = peer->burst = burst;
if (!clock_IsZero(&burstTime))
- conn->peer->burstWait = burstTime;
+ peer->burstWait = burstTime;
if (!clock_IsZero(&retryTime))
- conn->peer->rtt = _8THMSEC(&retryTime);
+ peer->rtt = _8THMSEC(&retryTime);
if (sendFile)
SendFile(sendFile, conn);
else {
strlen("So long, and thanks for all the fish!\n"));
}
if (debugFile)
- rx_PrintPeerStats(debugFile, rx_PeerOf(call->conn));
- rx_PrintPeerStats(stdout, rx_PeerOf(call->conn));
+ rx_PrintPeerStats(debugFile, rx_PeerOf(rx_ConnectionOf(call)));
+ rx_PrintPeerStats(stdout, rx_PeerOf(rx_ConnectionOf(call)));
return 0;
}
printf("Received file %s\n", rcvFile);
close(fd);
if (debugFile)
- rx_PrintPeerStats(debugFile, rx_PeerOf(call->conn));
- rx_PrintPeerStats(stdout, rx_PeerOf(call->conn));
+ rx_PrintPeerStats(debugFile, rx_PeerOf(rx_ConnectionOf(call)));
+ rx_PrintPeerStats(stdout, rx_PeerOf(rx_ConnectionOf(call)));
return 0;
}
if (PackageStatIndex[PackageIndex]) {
if (!split_flag) {
f_print(fout,
- "\t rx_IncrementTimeAndCount(z_conn->peer, %s,\n",
+ "\t rx_IncrementTimeAndCount(rx_PeerOf(z_conn), %s,\n",
PackageStatIndex[PackageIndex]);
} else {
f_print(fout,
- "\t rx_IncrementTimeAndCount(z_call->conn->peer, %s,\n",
+ "\t rx_IncrementTimeAndCount(rx_PeerOf(z_call->conn), %s,\n",
PackageStatIndex[PackageIndex]);
}
} else {
if (!split_flag) {
f_print(fout,
- "\t rx_IncrementTimeAndCount(z_conn->peer,\n"
+ "\t rx_IncrementTimeAndCount(rx_PeerOf(z_conn),\n"
"\t\t(((afs_uint32)(ntohs(z_conn->serviceId) << 16)) \n"
"\t\t| ((afs_uint32)ntohs(z_conn->peer->port))),\n");
} else {
f_print(fout,
- "\t rx_IncrementTimeAndCount(z_call->conn->peer,\n"
+ "\t rx_IncrementTimeAndCount(rx_PeerOf(z_call->conn),\n"
"\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
"\t\t((afs_uint32)ntohs(z_call->conn->peer->port))),\n");
}
f_print(fout, "\t clock_Sub(&__EXEC, &z_call->startTime);\n");
f_print(fout, "\t __QUEUE = z_call->startTime;\n");
f_print(fout, "\t clock_Sub(&__QUEUE, &z_call->queueTime);\n");
- f_print(fout, "\t rx_IncrementTimeAndCount(z_call->conn->peer,");
+ f_print(fout, "\t rx_IncrementTimeAndCount(rx_PeerOf(z_call->conn),");
if (PackageStatIndex[PackageIndex]) {
f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
} else {
f_print(fout, "\t __QUEUE = z_call->startTime;\n");
f_print(fout, "\t clock_Sub(&__QUEUE, &z_call->queueTime);\n");
f_print(fout,
- "\t rx_IncrementTimeAndCount(z_call->conn->peer,");
+ "\t rx_IncrementTimeAndCount(rx_PeerOf(z_call->conn),");
if (PackageStatIndex[PackageIndex]) {
f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
} else {
UNLOCK_CUID;
return 0;
}
- aconn->epoch = Cuid[0];
- aconn->cid = Cuid[1];
+ rx_SetConnectionEpoch(aconn, Cuid[0]);
+ rx_SetConnectionId(aconn, Cuid[1]);
Cuid[1] += 1 << RX_CIDSHIFT;
UNLOCK_CUID;
return 0;
{
afs_int32 i;
- aendpointp->cuid[0] = htonl(aconnp->epoch);
- i = aconnp->cid & RX_CIDMASK;
+ aendpointp->cuid[0] = htonl(rx_GetConnectionEpoch(aconnp));
+ i = rx_GetConnectionId(aconnp) & RX_CIDMASK;
aendpointp->cuid[1] = htonl(i);
aendpointp->cksum = 0; /* used as cksum only in chal resp. */
- aendpointp->securityIndex = htonl(aconnp->securityIndex);
+ aendpointp->securityIndex = htonl(rx_SecurityClassOf(aconnp));
return 0;
}
rxkad_NewConnection(struct rx_securityClass *aobj,
struct rx_connection *aconn)
{
- if (aconn->securityData)
+ if (rx_GetSecurityData(aconn) != NULL)
return RXKADINCONSISTENCY; /* already allocated??? */
if (rx_IsServerConn(aconn)) {
- int size = sizeof(struct rxkad_sconn);
- aconn->securityData = rxi_Alloc(size);
- memset(aconn->securityData, 0, size); /* initialize it conveniently */
+ struct rxkad_sconn *data;
+ data = rxi_Alloc(sizeof(struct rxkad_sconn));
+ memset(data, 0, sizeof(struct rxkad_sconn));
+ rx_SetSecurityData(aconn, data);
} else { /* client */
struct rxkad_cprivate *tcp;
- struct rxkad_cconn *tccp;
- int size = sizeof(struct rxkad_cconn);
- tccp = rxi_Alloc(size);
- aconn->securityData = (char *)tccp;
- memset(aconn->securityData, 0, size); /* initialize it conveniently */
+ struct rxkad_cconn *data;
+
+ data = rxi_Alloc(sizeof(struct rxkad_cconn));
+ memset(data, 0, sizeof(struct rxkad_cconn));
+ rx_SetSecurityData(aconn, data);
+
tcp = (struct rxkad_cprivate *)aobj->privateData;
if (!(tcp->type & rxkad_client))
return RXKADINCONSISTENCY;
rxkad_SetLevel(aconn, tcp->level); /* set header and trailer sizes */
rxkad_AllocCID(aobj, aconn); /* CHANGES cid AND epoch!!!! */
- rxkad_DeriveXORInfo(aconn, (fc_KeySchedule *)tcp->keysched, (char *)tcp->ivec, (char *)tccp->preSeq);
+ rxkad_DeriveXORInfo(aconn, (fc_KeySchedule *)tcp->keysched, (char *)tcp->ivec, (char *)data->preSeq);
INC_RXKAD_STATS(connections[rxkad_LevelIndex(tcp->level)]);
}
if (rx_IsServerConn(aconn)) {
struct rxkad_sconn *sconn;
struct rxkad_serverinfo *rock;
- sconn = (struct rxkad_sconn *)aconn->securityData;
+ sconn = rx_GetSecurityData(aconn);
if (sconn) {
- aconn->securityData = 0;
+ rx_SetSecurityData(aconn, NULL);
if (sconn->authenticated)
INC_RXKAD_STATS(destroyConn[rxkad_LevelIndex(sconn->level)]);
else
} else { /* client */
struct rxkad_cconn *cconn;
struct rxkad_cprivate *tcp;
- cconn = (struct rxkad_cconn *)aconn->securityData;
+ cconn = rx_GetSecurityData(aconn);
tcp = (struct rxkad_cprivate *)aobj->privateData;
if (!(tcp->type & rxkad_client))
return RXKADINCONSISTENCY;
if (cconn) {
- aconn->securityData = 0;
+ rx_SetSecurityData(aconn, NULL);
rxi_Free(cconn, sizeof(struct rxkad_cconn));
}
INC_RXKAD_STATS(destroyClient);
checkCksum = 0; /* init */
if (rx_IsServerConn(tconn)) {
struct rxkad_sconn *sconn;
- sconn = (struct rxkad_sconn *)tconn->securityData;
+ sconn = rx_GetSecurityData(tconn);
if (rx_GetPacketCksum(apacket) != 0)
sconn->cksumSeen = 1;
checkCksum = sconn->cksumSeen;
} else { /* client connection */
struct rxkad_cconn *cconn;
struct rxkad_cprivate *tcp;
- cconn = (struct rxkad_cconn *)tconn->securityData;
+ cconn = rx_GetSecurityData(tconn);
if (rx_GetPacketCksum(apacket) != 0)
cconn->cksumSeen = 1;
checkCksum = cconn->cksumSeen;
len = rx_GetDataSize(apacket);
if (rx_IsServerConn(tconn)) {
struct rxkad_sconn *sconn;
- sconn = (struct rxkad_sconn *)tconn->securityData;
+ sconn = rx_GetSecurityData(tconn);
if (sconn && sconn->authenticated
&& (osi_Time() < sconn->expirationTime)) {
level = sconn->level;
} else { /* client connection */
struct rxkad_cconn *cconn;
struct rxkad_cprivate *tcp;
- cconn = (struct rxkad_cconn *)tconn->securityData;
+ cconn = rx_GetSecurityData(tconn);
tcp = (struct rxkad_cprivate *)aobj->privateData;
if (!(tcp->type & rxkad_client))
return RXKADINCONSISTENCY;
rxkad_GetStats(struct rx_securityClass *aobj, struct rx_connection *aconn,
struct rx_securityObjectStats *astats)
{
+ void *securityData;
+
astats->type = 3;
astats->level = ((struct rxkad_cprivate *)aobj->privateData)->level;
- if (!aconn->securityData) {
+
+ securityData = rx_GetSecurityData(aconn);
+
+ if (!securityData) {
astats->flags |= 1;
return 0;
}
if (rx_IsServerConn(aconn)) {
- struct rxkad_sconn *sconn;
- sconn = (struct rxkad_sconn *)aconn->securityData;
+ struct rxkad_sconn *sconn = securityData;
+
astats->level = sconn->level;
if (sconn->authenticated)
astats->flags |= 2;
astats->bytesSent = sconn->stats.bytesSent;
astats->packetsSent = sconn->stats.packetsSent;
} else { /* client connection */
- struct rxkad_cconn *cconn;
- cconn = (struct rxkad_cconn *)aconn->securityData;
+ struct rxkad_cconn *cconn = securityData;
+
if (cconn->cksumSeen)
astats->flags |= 8;
astats->bytesReceived = cconn->stats.bytesReceived;
rxkad_CheckAuthentication(struct rx_securityClass *aobj,
struct rx_connection *aconn)
{
- struct rxkad_sconn *sconn;
+ struct rxkad_sconn *sconn = rx_GetSecurityData(aconn);
/* first make sure the object exists */
- if (!aconn->securityData)
+ if (!sconn)
return RXKADINCONSISTENCY;
- sconn = (struct rxkad_sconn *)aconn->securityData;
return !sconn->authenticated;
}
rxkad_CreateChallenge(struct rx_securityClass *aobj,
struct rx_connection *aconn)
{
- struct rxkad_sconn *sconn;
+ struct rxkad_sconn *sconn = rx_GetSecurityData(aconn);
struct rxkad_sprivate *tsp;
- sconn = (struct rxkad_sconn *)aconn->securityData;
sconn->challengeID = get_random_int32();
sconn->authenticated = 0; /* conn unauth. 'til we hear back */
/* initialize level from object's minimum acceptable level */
rxkad_GetChallenge(struct rx_securityClass *aobj, struct rx_connection *aconn,
struct rx_packet *apacket)
{
- struct rxkad_sconn *sconn;
+ struct rxkad_sconn *sconn = rx_GetSecurityData(aconn);
char *challenge;
int challengeSize;
struct rxkad_v2Challenge c_v2; /* version 2 */
struct rxkad_oldChallenge c_old; /* old style */
- sconn = (struct rxkad_sconn *)aconn->securityData;
if (rx_IsUsingPktCksum(aconn))
sconn->cksumSeen = 1;
unsigned int pos;
struct rxkad_serverinfo *rock;
- sconn = (struct rxkad_sconn *)aconn->securityData;
+ sconn = rx_GetSecurityData(aconn);
tsp = (struct rxkad_sprivate *)aobj->privateData;
if (sconn->cksumSeen) {
{
struct rxkad_sconn *sconn;
- sconn = (struct rxkad_sconn *)aconn->securityData;
+ sconn = rx_GetSecurityData(aconn);
if (sconn && sconn->authenticated && sconn->rock
&& (time(0) < sconn->expirationTime)) {
if (level)
rx_rdwr.o \
rx_stats.o \
rx_trace.o \
- rx_multi.o
+ rx_multi.o \
+ rx_conn.o
RXSTATOBJS =\
rxstat.o \
rx_conncache.o: ${RX}/rx_conncache.c
$(AFS_CCRULE) $(RX)/rx_conncache.c
+rx_conn.o : ${RX}/rx_conn.c
+ $(AFS_CCRULE) $(RX)/rx_conn.c
+
rx_null.o: ${RX}/rx_null.c
$(AFS_CCRULE) $(RX)/rx_null.c
rx_identity_free;
rx_InterruptCall;
rx_SetBusyChannelError;
+ rx_PeerOf;
+ rx_SecurityClassOf;
+ rx_ServiceIdOf;
+ rx_SecurityObjectOf;
+ rx_ConnError;
local:
*;
};
afs_int32 error;
*errornumber = 0;
- SETCLIENTCONTEXT(blob, rx_HostOf(call->conn->peer), creds->uid,
+ SETCLIENTCONTEXT(blob, rx_HostOf(rx_PeerOf(call->conn)), creds->uid,
creds->group0, creds->group1, PSETPAG, NFS_EXPORTER);
data.in = (caddr_t) blob;
data.in_size = sizeof(blob);
afs_uint32 blob[PIOCTL_HEADER];
*errornumber = 0;
- SETCLIENTCONTEXT(blob, rx_HostOf(call->conn->peer), creds->uid,
+ SETCLIENTCONTEXT(blob, rx_HostOf(rx_PeerOf(call->conn)), creds->uid,
creds->group0, creds->group1, cmd, NFS_EXPORTER);
data.in =
(char *)malloc(InData->rmtbulk_len +
if (!FidArray && !CallBackArray) {
ViceLog(1,
("SAFS_GiveUpAllCallBacks: host=%x\n",
- (tcon->peer ? tcon->peer->host : 0)));
+ (rx_PeerOf(tcon) ? rx_PeerOf(tcon)->host : 0)));
errorCode = GetClient(tcon, &client);
if (!errorCode) {
H_LOCK;
ViceLog(0,
("GiveUpCallBacks: #Fids %d < #CallBacks %d, host=%x\n",
FidArray->AFSCBFids_len, CallBackArray->AFSCBs_len,
- (tcon->peer ? tcon->peer->host : 0)));
+ (rx_PeerOf(tcon) ? rx_PeerOf(tcon)->host : 0)));
errorCode = EINVAL;
goto Bad_GiveUpCallBacks;
}
int created = 0;
client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
- if (client && client->sid == rxr_CidOf(tcon)
- && client->VenusEpoch == rxr_GetEpoch(tcon)
+ if (client && client->sid == rx_GetConnectionId(tcon)
+ && client->VenusEpoch == rx_GetConnectionEpoch(tcon)
&& !(client->host->hostFlags & HOSTDELETED)
&& !client->deleted) {
retryfirstclient:
/* First try to find the client structure */
for (client = host->FirstClient; client; client = client->next) {
- if (!client->deleted && (client->sid == rxr_CidOf(tcon))
- && (client->VenusEpoch == rxr_GetEpoch(tcon))) {
+ if (!client->deleted && (client->sid == rx_GetConnectionId(tcon))
+ && (client->VenusEpoch == rx_GetConnectionEpoch(tcon))) {
client->refCount++;
H_UNLOCK;
ObtainWriteLock(&client->lock);
}
/* Retry to find the client structure */
for (client = host->FirstClient; client; client = client->next) {
- if (!client->deleted && (client->sid == rxr_CidOf(tcon))
- && (client->VenusEpoch == rxr_GetEpoch(tcon))) {
+ if (!client->deleted && (client->sid == rx_GetConnectionId(tcon))
+ && (client->VenusEpoch == rx_GetConnectionEpoch(tcon))) {
h_Unlock_r(host);
goto retryfirstclient;
}
client->ViceId = viceid;
client->expTime = expTime; /* rx only */
client->authClass = authClass; /* rx only */
- client->sid = rxr_CidOf(tcon);
- client->VenusEpoch = rxr_GetEpoch(tcon);
+ client->sid = rx_GetConnectionId(tcon);
+ client->VenusEpoch = rx_GetConnectionEpoch(tcon);
client->CPS.prlist_val = NULL;
client->CPS.prlist_len = 0;
h_Unlock_r(host);
* the RPC from the other client structure's rock.
*/
oldClient = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
- if (oldClient && oldClient != client && oldClient->sid == rxr_CidOf(tcon)
- && oldClient->VenusEpoch == rxr_GetEpoch(tcon)
+ if (oldClient && oldClient != client
+ && oldClient->sid == rx_GetConnectionId(tcon)
+ && oldClient->VenusEpoch == rx_GetConnectionEpoch(tcon)
&& !(oldClient->host->hostFlags & HOSTDELETED)) {
char hoststr[16];
if (!oldClient->deleted) {
oldClient, oldClient->sid, oldClient->refCount,
oldClient->host, oldClient->host->refCount, tcon,
afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
- ntohs(rxr_PortOf(tcon)), rxr_CidOf(tcon),
+ ntohs(rxr_PortOf(tcon)), rx_GetConnectionId(tcon),
client, client->sid, client->refCount,
client->host, client->host->refCount));
/* rx_SetSpecific will be done immediately below */
H_UNLOCK;
return VBUSY;
}
- if (rxr_CidOf(tcon) != client->sid || rxr_GetEpoch(tcon) != client->VenusEpoch) {
+ if (rx_GetConnectionId(tcon) != client->sid
+ || rx_GetConnectionEpoch(tcon) != client->VenusEpoch) {
ViceLog(0,
("GetClient: tcon %p tcon sid %d client sid %d\n",
- tcon, rxr_CidOf(tcon), client->sid));
+ tcon, rx_GetConnectionId(tcon), client->sid));
H_UNLOCK;
return VBUSY;
}
ViceLog(0, ("GetClient: got deleted client, connection will appear "
"anonymous; tcon %p cid %x client %p ref %d host %p "
"(%s:%d) href %d ViceId %d\n",
- tcon, rxr_CidOf(tcon), client, client->refCount,
+ tcon, rx_GetConnectionId(tcon), client, client->refCount,
client->host,
afs_inet_ntoa_r(client->host->host, hoststr),
(int)ntohs(client->host->port), client->host->refCount,
if (rxConn == 0)
break;
rx_SetConnDeadTime(rxConn, rx_connDeadTime);
- if (rxConn->service)
- rxConn->service->connDeadTime = rx_connDeadTime;
+ if (rx_ServiceOf(rxConn))
+ rx_ServiceOf(rxConn)->connDeadTime = rx_connDeadTime;
}
avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
if (rxConn == 0)
break;
rx_SetConnDeadTime(rxConn, rx_connDeadTime);
- if (rxConn->service)
- rxConn->service->connDeadTime = rx_connDeadTime;
+ if (rx_ServiceOf(rxConn))
+ rx_ServiceOf(rxConn)->connDeadTime = rx_connDeadTime;
}
avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
#define CTX_FOR_RXCALL(call) \
- (rx_GetServiceSpecific((rx_ConnectionOf(call))->service, ctx_key))
+ (rx_GetServiceSpecific((rx_ServiceOf(rx_ConnectionOf(call))), ctx_key))
afs_int32 rpc_test_PkgInit();
void rpc_test_PkgShutdown();