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
"Welcome to our mercurial repository"