kdp_return_t kdp_exception_wait (kdp_connection *c, kdp_pkt_t * response, int timeout) { if (c->saved_exception_pending) { memcpy (response, c->saved_exception, KDP_MAX_PACKET_SIZE); c->saved_exception_pending = 0; c->logger (KDP_LOG_DEBUG, "kdp_exception_wait: " "returning previously saved exception (sequence number is %d)", response->hdr.seq); return RR_SUCCESS; } for (;;) { kdp_return_t kdpret; kdpret = kdp_receive_exception (c, response, timeout); if (kdpret != RR_SUCCESS) { return kdpret; } kdpret = kdp_exception_reply (c, response); if (kdpret != RR_SUCCESS) { return kdpret; } if (response->hdr.seq == c->exc_seqno) { c->exc_seqno = (c->exc_seqno + 1) % 256; c->logger (KDP_LOG_DEBUG, "kdp_exception_wait: " "returning previously saved exception (sequence number is %d)", response->hdr.seq); break; } else if (((response->hdr.seq + 1) % 256) == c->exc_seqno) { /* duplicate of previous exception */ c->logger (KDP_LOG_DEBUG, "kdp_reply_wait: " "ignoring duplicate of previous exception (sequence number was %d)\n", response->hdr.seq); continue; } else { c->logger (KDP_LOG_ERROR, "kdp_exception_wait: " "unexpected sequence number for exception (expected %d, got %d)\n", c->exc_seqno, response->hdr.seq); continue; } } return RR_SUCCESS; }
kdp_return_t kdp_reply_wait (kdp_connection *c, kdp_pkt_t *response, int timeout) { for (;;) { kdp_return_t kdpret; kdpret = kdp_receive (c, response, timeout); if (kdpret != RR_SUCCESS) { c->logger (KDP_LOG_ERROR, "kdp_reply_wait: error from kdp_receive: %s\n", kdp_return_string (kdpret)); return kdpret; } if (response->hdr.request == KDP_EXCEPTION) { kdpret = kdp_exception_reply (c, response); if (kdpret != RR_SUCCESS) { c->logger (KDP_LOG_ERROR, "kdp_reply_wait: error from kdp_exception_reply: %s\n", kdp_return_string (kdpret)); return kdpret; } if (response->hdr.seq == c->exc_seqno) { c->exc_seqno = (c->exc_seqno + 1) % 256; /* save for future processing */ if (c->saved_exception_pending) { c->logger (KDP_LOG_ERROR, "kdp_reply_wait: " "unable to save exception for future processing; ignoring\n"); c->logger (KDP_LOG_ERROR, "kdp_reply_wait: " "exception had sequence number %d\n", response->hdr.seq); return RR_IP_ERROR; } c->logger (KDP_LOG_DEBUG, "kdp_reply_wait: " "saving exception for future processing (sequence number is %d)\n", response->hdr.seq); memcpy (c->saved_exception, response, KDP_MAX_PACKET_SIZE); c->saved_exception_pending = 1; continue; } else if (((response->hdr.seq + 1) % 256) == c->exc_seqno) { /* duplicate of previous exception */ c->logger (KDP_LOG_DEBUG, "kdp_reply_wait: " "ignoring duplicate of previous exception (sequence number was %d)\n", response->hdr.seq); continue; } else { c->logger (KDP_LOG_ERROR, "kdp_reply_wait: " "unexpected sequence number for exception (expected %d, got %d)\n", c->exc_seqno, response->hdr.seq); continue; } } else { if (response->hdr.seq == c->seqno) { c->seqno = (c->seqno + 1) % 256; /* return reply */ c->logger (KDP_LOG_DEBUG, "kdp_reply_wait: " "returning reply (sequence number is %d)\n", response->hdr.seq); break; } else if (((response->hdr.seq + 1) % 256) == c->exc_seqno) { /* duplicate of previous response */ c->logger (KDP_LOG_DEBUG, "kdp_reply_wait: " "ignoring duplicate of previous reply (sequence number was %d)\n", response->hdr.seq); continue; } else { c->logger (KDP_LOG_ERROR, "kdp_reply_wait: " "unexpected sequence number for reply (expected %d, got %d)\n", c->seqno, response->hdr.seq); continue; } } } return RR_SUCCESS; }