Mercurial > hg > freeDiameter
comparison extensions/rt_busypeers/rtbusy.c @ 1279:a1685a53fe97
When requests fall into timeout, log them, the timeout, and the slow peer.
Fix a typo in a variable name while here.
author | Thomas Klausner <tk@giga.or.at> |
---|---|
date | Fri, 12 Sep 2014 14:47:38 +0200 |
parents | 1af09cc156d6 |
children | ab6457399be2 |
comparison
equal
deleted
inserted
replaced
1278:2a7b32176d2e | 1279:a1685a53fe97 |
---|---|
47 int rt_busy_process_busy(struct msg ** pmsg, int is_req, DiamId_t sentto, size_t senttolen, union avp_value *oh) | 47 int rt_busy_process_busy(struct msg ** pmsg, int is_req, DiamId_t sentto, size_t senttolen, union avp_value *oh) |
48 { | 48 { |
49 struct msg * qry = NULL; | 49 struct msg * qry = NULL; |
50 struct rt_data * rtd = NULL; | 50 struct rt_data * rtd = NULL; |
51 struct fd_list * candidates = NULL; | 51 struct fd_list * candidates = NULL; |
52 int sendingattemtps; | 52 int sendingattempts; |
53 int resend = 1; | 53 int resend = 1; |
54 | 54 |
55 | 55 |
56 TRACE_ENTRY("%p(%p) %d %p %p", pmsg, pmsg?*pmsg:NULL, is_req, sentto, oh); | 56 TRACE_ENTRY("%p(%p) %d %p %p", pmsg, pmsg?*pmsg:NULL, is_req, sentto, oh); |
57 | 57 |
70 CHECK_FCT( fd_rtd_error_add(rtd, | 70 CHECK_FCT( fd_rtd_error_add(rtd, |
71 sentto, senttolen, | 71 sentto, senttolen, |
72 (uint8_t *)(oh ? (DiamId_t)oh->os.data : fd_g_config->cnf_diamid), oh ? oh->os.len : fd_g_config->cnf_diamid_len , | 72 (uint8_t *)(oh ? (DiamId_t)oh->os.data : fd_g_config->cnf_diamid), oh ? oh->os.len : fd_g_config->cnf_diamid_len , |
73 ER_DIAMETER_TOO_BUSY, | 73 ER_DIAMETER_TOO_BUSY, |
74 &candidates, | 74 &candidates, |
75 &sendingattemtps) ); | 75 &sendingattempts) ); |
76 | 76 |
77 /* Now we need to decide if we re-send this query to a different peer or return an error to upstream */ | 77 /* Now we need to decide if we re-send this query to a different peer or return an error to upstream */ |
78 | 78 |
79 /* First, are we exceeding the allowed attempts? */ | 79 /* First, are we exceeding the allowed attempts? */ |
80 if (rtbusy_conf.RetryMaxPeers != 0) { | 80 if (rtbusy_conf.RetryMaxPeers != 0) { |
81 if (sendingattemtps >= rtbusy_conf.RetryMaxPeers) { | 81 if (sendingattempts >= rtbusy_conf.RetryMaxPeers) { |
82 TRACE_DEBUG(FULL, "Maximum number of sending attempts reached for message %p, returning an error upstream", qry); | 82 TRACE_DEBUG(FULL, "Maximum number of sending attempts reached for message %p, returning an error upstream", qry); |
83 resend = 0; | 83 resend = 0; |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
104 CHECK_FCT( fd_msg_free(*pmsg) ); | 104 CHECK_FCT( fd_msg_free(*pmsg) ); |
105 *pmsg = qry; | 105 *pmsg = qry; |
106 } | 106 } |
107 /* Send the query again. We need to re-associate the expirecb which was cleaned, if it is used */ | 107 /* Send the query again. We need to re-associate the expirecb which was cleaned, if it is used */ |
108 if (rtbusy_conf.RelayTimeout) { | 108 if (rtbusy_conf.RelayTimeout) { |
109 char *buf = NULL; | |
110 size_t len; | |
109 struct timespec expire; | 111 struct timespec expire; |
110 CHECK_SYS( clock_gettime(CLOCK_REALTIME, &expire) ); | 112 CHECK_SYS( clock_gettime(CLOCK_REALTIME, &expire) ); |
111 expire.tv_sec += rtbusy_conf.RelayTimeout/1000 + ((expire.tv_nsec + (1000000LL * (rtbusy_conf.RelayTimeout % 1000))) / 1000000000LL); | 113 expire.tv_sec += rtbusy_conf.RelayTimeout/1000 + ((expire.tv_nsec + (1000000LL * (rtbusy_conf.RelayTimeout % 1000))) / 1000000000LL); |
112 expire.tv_nsec = (expire.tv_nsec + (1000000LL * (rtbusy_conf.RelayTimeout % 1000))) % 1000000000LL; | 114 expire.tv_nsec = (expire.tv_nsec + (1000000LL * (rtbusy_conf.RelayTimeout % 1000))) % 1000000000LL; |
115 CHECK_MALLOC_DO( fd_msg_dump_full(&buf, &len, NULL, *pmsg, fd_g_config->cnf_dict, 0, 1), /* nothing */); | |
116 TRACE_ERROR( "No answer received for message from peer '%.*s' before timeout (%dms), re-sending: %s", senttolen, sentto, | |
117 rtbusy_conf.RelayTimeout, buf); | |
118 free(buf); | |
113 CHECK_FCT( fd_msg_send_timeout( pmsg, NULL, NULL, rtbusy_expirecb, &expire ) ); | 119 CHECK_FCT( fd_msg_send_timeout( pmsg, NULL, NULL, rtbusy_expirecb, &expire ) ); |
114 } else { | 120 } else { |
115 CHECK_FCT( fd_msg_send(pmsg, NULL, NULL) ); | 121 CHECK_FCT( fd_msg_send(pmsg, NULL, NULL) ); |
116 } | 122 } |
117 | 123 |
118 } else { | 124 } else { |
119 if (is_req) { | 125 if (is_req) { |
126 char *buf = NULL; | |
127 size_t len; | |
128 | |
129 CHECK_MALLOC_DO( fd_msg_dump_full(&buf, &len, NULL, *pmsg, fd_g_config->cnf_dict, 0, 1), /* nothing */); | |
130 TRACE_ERROR( "No answer received for message from peer '%.*s' before timeout (%dms), giving up and sending error reply: %s", senttolen, sentto, | |
131 rtbusy_conf.RelayTimeout, buf); | |
132 free(buf); | |
120 /* We must create an answer */ | 133 /* We must create an answer */ |
121 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, pmsg, MSGFL_ANSW_ERROR ) ); | 134 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, pmsg, MSGFL_ANSW_ERROR ) ); |
122 | 135 |
123 CHECK_FCT( fd_msg_rescode_set(*pmsg, "DIAMETER_TOO_BUSY", "[rt_busypeers] Timeout reached while waiting for an answer", NULL, 1 ) ); | 136 CHECK_FCT( fd_msg_rescode_set(*pmsg, "DIAMETER_TOO_BUSY", "[rt_busypeers] Timeout reached while waiting for an answer", NULL, 1 ) ); |
124 | 137 |