service->minProcs = 0;
service->maxProcs = 1;
service->idleDeadTime = 60;
+ service->idleDeadErr = 0;
service->connDeadTime = rx_connDeadTime;
service->executeRequestProc = serviceProc;
service->checkReach = 0;
conn->specific = NULL;
rx_SetConnDeadTime(conn, service->connDeadTime);
rx_SetConnIdleDeadTime(conn, service->idleDeadTime);
+ rx_SetServerConnIdleDeadErr(conn, service->idleDeadErr);
for (i = 0; i < RX_MAXCALLS; i++) {
conn->twind[i] = rx_initSendWindow;
conn->rwind[i] = rx_initReceiveWindow;
/* Update last send time for this call (for keep-alive
* processing), and for the connection (so that we can discover
* idle connections) */
- conn->lastSendTime = call->lastSendTime = clock_Sec();
+ call->lastSendData = conn->lastSendTime = call->lastSendTime = clock_Sec();
}
/* When sending packets we need to follow these rules:
* processing), and for the connection (so that we can discover
* idle connections) */
conn->lastSendTime = call->lastSendTime = clock_Sec();
+ /* Don't count keepalives here, so idleness can be tracked. */
+ if (p->header.type != RX_PACKET_TYPE_ACK)
+ call->lastSendData = call->lastSendTime;
}
return -1;
}
}
+ if (call->lastSendData && conn->idleDeadTime && (conn->idleDeadErr != 0)
+ && ((call->lastSendData + conn->idleDeadTime) < now)) {
+ if (call->state == RX_STATE_ACTIVE) {
+ rxi_CallError(call, conn->idleDeadErr);
+ return -1;
+ }
+ }
/* see if we have a hard timeout */
if (conn->hardDeadTime
&& (now > (conn->hardDeadTime + call->startTime.sec))) {
/* Define procedure to set service dead time */
#define rx_SetIdleDeadTime(service,time) ((service)->idleDeadTime = (time))
+/* Define error to return in server connections when failing to answer */
+#define rx_SetServerIdleDeadErr(service,err) ((service)->idleDeadErr = (err))
+
/* Define procedures for getting and setting before and after execute-request procs */
#define rx_SetAfterProc(service,proc) ((service)->afterProc = (proc))
#define rx_SetBeforeProc(service,proc) ((service)->beforeProc = (proc))
/* Set connection hard and idle timeouts for a connection */
#define rx_SetConnHardDeadTime(conn, seconds) ((conn)->hardDeadTime = (seconds))
#define rx_SetConnIdleDeadTime(conn, seconds) ((conn)->idleDeadTime = (seconds))
+#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))
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;
int nSpecific; /* number entries in specific data */
void **specific; /* pointer to connection specific data */
};
u_short connDeadTime; /* Seconds until a client of this service will be declared dead, if it is not responding */
u_short idleDeadTime; /* Time a server will wait for I/O to start up again */
u_char checkReach; /* Check for asymmetric clients? */
+ afs_int32 idleDeadErr;
};
#endif /* KDUMP_RX_LOCK */
int abortCount; /* number of times last error was sent */
u_int lastSendTime; /* Last time a packet was sent on this call */
u_int lastReceiveTime; /* Last time a packet was received for this call */
+ u_int lastSendData; /* Last time a nonping was sent on this call */
void (*arrivalProc) (register struct rx_call * call, register void * mh, register int index); /* Procedure to call when reply is received */
void *arrivalProcHandle; /* Handle to pass to replyFunc */
int arrivalProcArg; /* Additional arg to pass to reply Proc */
rx_SetMinProcs(tservice, 3);
rx_SetMaxProcs(tservice, lwps);
rx_SetCheckReach(tservice, 1);
+ rx_SetServerIdleDeadErr(tservice, VNOSERVICE);
tservice =
rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4,