-static void send_req(p)
-proto_t *p;
-{
- dgram_t outmsg;
-
- setup_dgram(p, &outmsg, p->security, "REQ");
- dgram_cat(&outmsg, p->req);
-
-#ifdef PROTO_DEBUG
- dbprintf(("%s: send_req: len %d: packet:\n----\n%s----\n\n",
- debug_prefix_time(": protocol"),
- outmsg.len,
- outmsg.data));
-#endif
-
- if(dgram_send_addr(p->peer, &outmsg))
- fprintf(stderr,"send req failed: %s\n", strerror(errno));
-}
-
-static void send_ack(p)
-proto_t *p;
-{
- dgram_t outmsg;
-
- setup_dgram(p, &outmsg, NULL, "ACK");
-
-#ifdef PROTO_DEBUG
- dbprintf(("%s: send_ack: len %d: packet:\n----\n%s----\n\n",
- debug_prefix_time(": protocol"),
- outmsg.len,
- outmsg.data));
-#endif
-
- if(dgram_send_addr(p->peer, &outmsg))
- error("send ack failed: %s", strerror(errno));
-}
-
-static void send_ack_repl(pkt)
-pkt_t *pkt;
-{
- dgram_t outmsg;
- char *linebuf = NULL;
- char major_str[NUM_STR_SIZE];
- char minor_str[NUM_STR_SIZE];
- char seq_str[NUM_STR_SIZE];
-
- ap_snprintf(major_str, sizeof(major_str), "%d", VERSION_MAJOR);
- ap_snprintf(minor_str, sizeof(minor_str), "%d", VERSION_MINOR);
- ap_snprintf(seq_str, sizeof(seq_str), "%d", pkt->sequence);
-
- dgram_zero(&outmsg);
- dgram_socket(&outmsg,proto_socket);
-
- linebuf = vstralloc("Amanda ", major_str, ".", minor_str,
- " ACK HANDLE ", pkt->handle,
- " SEQ ", seq_str,
- "\n", NULL);
-
- dgram_cat(&outmsg, linebuf);
- amfree(linebuf);
-
-#ifdef PROTO_DEBUG
- dbprintf(("%s: send_ack_repl: len %d: packet:\n----\n%s----\n\n",
- debug_prefix_time(": protocol"),
- outmsg.len,
- outmsg.data));
-#endif
-
- if(dgram_send_addr(pkt->peer, &outmsg))
- error("send ack failed: %s", strerror(errno));
-}
-
-
-static void state_machine(p, action, pkt)
-proto_t *p;
-action_t action;
-pkt_t *pkt;
-{
-
-#ifdef PROTO_DEBUG
- dbprintf(("%s: state_machine: p %X state %s action %s%s%s\n",
- debug_prefix_time(": protocol"),
- (int)p,
- prnpstate(p->state),
- prnaction(action),
- pkt == NULL? "" : " pktype ",
- pkt == NULL? "" : prnpktype(pkt->type)));
-#endif
-
- while(1) {
- p->prevstate = p->state;
- switch(p->state) {
- case S_STARTUP:
- if(action != A_START) goto badaction;
- p->origseq = p->curseq = proto_global_seq++;
- p->reqtries = REQ_TRIES;
- p->state = S_SENDREQ;
- p->acktries = ACK_TRIES;
- alloc_handle(p);
- break;
-
- case S_SENDREQ:
- send_req(p);
- p->curtime = CURTIME;
- if(p->curseq == p->origseq) p->origtime = p->curtime;
- p->timeout = time(0) + ACK_WAIT;
- p->state = S_ACKWAIT;
- pending_enqueue(p);
- return;
-
- case S_ACKWAIT:
- if(action == A_TIMEOUT) {
- if(--p->acktries == 0) {
- p->state = S_FAILED;
- free_handle(p);
- p->continuation(p, NULL);
- amfree(p->req);
- amfree(p->security);
- amfree(p);
- return;
- }
- else {
- p->state = S_SENDREQ;
- break;
- }
- }
- else if(action != A_RCVDATA)
- goto badaction;
-
- /* got the packet with the right handle, now check it */
-
-#ifdef PROTO_DEBUG
- dbprintf((
- "%s: RESPTIME p %X pkt %s (t %d s %d) orig (t %d s %d) cur (t %d s %d)\n",
- debug_prefix_time(": protocol"),
- (int)p, prnpktype(pkt->type),
- (int)CURTIME, relseq(pkt->sequence),
- (int)p->origtime, relseq(p->origseq),
- (int)p->curtime, relseq(p->curseq)));
-#endif
-
- if(pkt->type == P_ACK) {
- if(pkt->sequence != p->origseq)
- p->reqtries--;
- p->state = S_REPWAIT;
- p->timeout = time(0) + p->repwait;
- pending_enqueue(p);
- return;
- }
- else if(pkt->type == P_NAK) {
- p->state = S_FAILED;
- free_handle(p);
- p->continuation(p, pkt);
- amfree(p->req);
- amfree(p->security);
- amfree(p);
- return;
- }
- else if(pkt->type == P_REP) {
- /* no ack, just rep */
- p->state = S_REPWAIT;
- break;
- }
- else if(pkt->type == P_PREP) {
- /* no ack, just rep */
- p->state = S_REPWAIT;
- break;
- }
- /* else unexpected packet, put back on queue */
- pending_enqueue(p);
- return;