# HG changeset patch # User Sebastien Decugis # Date 1264557414 -32400 # Node ID 4679ff581d6a2451a226d0eee76918f6515c5e83 # Parent 6f6fd233b9235d4eed1b1b86aff58c6dc057843a Fix invalid restore of the hop-by-hop id on forwarded answers diff -r 6f6fd233b923 -r 4679ff581d6a freeDiameter/fD.h --- a/freeDiameter/fD.h Tue Jan 26 14:44:32 2010 +0900 +++ b/freeDiameter/fD.h Wed Jan 27 10:56:54 2010 +0900 @@ -279,7 +279,7 @@ void fd_p_cnx_abort(struct fd_peer * peer, int cleanup_all); /* Peer sent requests cache */ -int fd_p_sr_store(struct sr_list * srlist, struct msg **req, uint32_t *hbhloc); +int fd_p_sr_store(struct sr_list * srlist, struct msg **req, uint32_t *hbhloc, uint32_t hbh_restore); int fd_p_sr_fetch(struct sr_list * srlist, uint32_t hbh, struct msg **req); void fd_p_sr_failover(struct sr_list * srlist); diff -r 6f6fd233b923 -r 4679ff581d6a freeDiameter/p_out.c --- a/freeDiameter/p_out.c Tue Jan 26 14:44:32 2010 +0900 +++ b/freeDiameter/p_out.c Wed Jan 27 10:56:54 2010 +0900 @@ -43,6 +43,7 @@ uint8_t * buf; size_t sz; int ret; + uint32_t bkp_hbh = 0; TRACE_ENTRY("%p %p %p %p", msg, cnx, hbh, srl); @@ -53,6 +54,7 @@ if (msg_is_a_req) { CHECK_PARAMS(hbh && srl); /* Alloc the hop-by-hop id and increment the value for next message */ + bkp_hbh = hdr->msg_hbhid; hdr->msg_hbhid = *hbh; *hbh = hdr->msg_hbhid + 1; } @@ -70,7 +72,7 @@ /* Save a request before sending so that there is no race condition with the answer */ if (msg_is_a_req) { - CHECK_FCT_DO( ret = fd_p_sr_store(srl, msg, &hdr->msg_hbhid), { free(buf); return ret; } ); + CHECK_FCT_DO( ret = fd_p_sr_store(srl, msg, &hdr->msg_hbhid, bkp_hbh), { free(buf); return ret; } ); } /* Send the message */ diff -r 6f6fd233b923 -r 4679ff581d6a freeDiameter/p_sr.c --- a/freeDiameter/p_sr.c Tue Jan 26 14:44:32 2010 +0900 +++ b/freeDiameter/p_sr.c Wed Jan 27 10:56:54 2010 +0900 @@ -43,6 +43,7 @@ struct sentreq { struct fd_list chain; /* the "o" field points directly to the hop-by-hop of the request (uint32_t *) */ struct msg *req; /* A request that was sent and not yet answered. */ + uint32_t prevhbh;/* The value to set in the hbh header when the message is retrieved */ }; /* Find an element in the list, or the following one */ @@ -76,19 +77,20 @@ } /* Store a new sent request */ -int fd_p_sr_store(struct sr_list * srlist, struct msg **req, uint32_t *hbhloc) +int fd_p_sr_store(struct sr_list * srlist, struct msg **req, uint32_t *hbhloc, uint32_t hbh_restore) { struct sentreq * sr; struct fd_list * next; int match; - TRACE_ENTRY("%p %p %p", srlist, req, hbhloc); + TRACE_ENTRY("%p %p %p %x", srlist, req, hbhloc, hbh_restore); CHECK_PARAMS(srlist && req && *req && hbhloc); CHECK_MALLOC( sr = malloc(sizeof(struct sentreq)) ); memset(sr, 0, sizeof(struct sentreq)); fd_list_init(&sr->chain, hbhloc); sr->req = *req; + sr->prevhbh = hbh_restore; /* Search the place in the list */ CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) ); @@ -122,9 +124,11 @@ srl_dump("Fetching a request, ", &srlist->srs); sr = (struct sentreq *)find_or_next(&srlist->srs, hbh, &match); if (!match) { - TRACE_DEBUG(INFO, "There is no saved request with this hop-by-hop id"); + TRACE_DEBUG(INFO, "There is no saved request with this hop-by-hop id (%x)", hbh); *req = NULL; } else { + /* Restore hop-by-hop id */ + *((uint32_t *)sr->chain.o) = sr->prevhbh; /* Unlink */ fd_list_unlink(&sr->chain); *req = sr->req;