/src/kamailio/src/core/error.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2001-2003 FhG Fokus |
3 | | * |
4 | | * This file is part of Kamailio, a free SIP server. |
5 | | * |
6 | | * Kamailio is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version |
10 | | * |
11 | | * Kamailio is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | * |
20 | | */ |
21 | | |
22 | | /*! |
23 | | * \file |
24 | | * \brief Kamailio core :: Error handling |
25 | | * \ingroup core |
26 | | * Module: \ref core |
27 | | */ |
28 | | |
29 | | |
30 | | #include <stdio.h> |
31 | | #include "error.h" |
32 | | #include "str.h" |
33 | | #include "parser/msg_parser.h" |
34 | | #include "mem/mem.h" |
35 | | |
36 | | /* current function's error; */ |
37 | | int ser_error = -1; |
38 | | /* previous error */ |
39 | | int prev_ser_error = -1; |
40 | | |
41 | | int err2reason_phrase(int int_error, /* current internal error */ |
42 | | int *sip_error, /* corresponding sip response code */ |
43 | | char *phrase, /* resulting error text */ |
44 | | int etl, /* error text buffer length */ |
45 | | char *signature) /* extra text to be appended */ |
46 | 0 | { |
47 | |
|
48 | 0 | char *error_txt; |
49 | |
|
50 | 0 | switch(int_error) { |
51 | 0 | case E_SEND: |
52 | 0 | error_txt = "Unfortunately error on sending to next hop occurred"; |
53 | 0 | *sip_error = -int_error; |
54 | 0 | break; |
55 | 0 | case E_BAD_ADDRESS: |
56 | 0 | error_txt = "Unresolvable destination"; |
57 | 0 | *sip_error = -int_error; |
58 | 0 | break; |
59 | 0 | case E_BAD_REQ: |
60 | 0 | error_txt = "Bad Request"; |
61 | 0 | *sip_error = -int_error; |
62 | 0 | break; |
63 | 0 | case E_BAD_URI: |
64 | 0 | error_txt = "Regretfully, we were not able to process the URI"; |
65 | 0 | *sip_error = -int_error; |
66 | 0 | break; |
67 | 0 | case E_BAD_TUPEL: |
68 | 0 | error_txt = "Transaction tuple incomplete"; |
69 | 0 | *sip_error = -E_BAD_REQ; |
70 | 0 | break; |
71 | 0 | case E_BAD_TO: |
72 | 0 | error_txt = "Bad To"; |
73 | 0 | *sip_error = -E_BAD_REQ; |
74 | 0 | break; |
75 | 0 | case E_EXEC: |
76 | 0 | error_txt = "Error in external logic"; |
77 | 0 | *sip_error = -E_BAD_SERVER; |
78 | 0 | break; |
79 | 0 | case E_TOO_MANY_BRANCHES: |
80 | 0 | error_txt = "Forking capacity exceeded"; |
81 | 0 | *sip_error = -E_BAD_SERVER; |
82 | 0 | break; |
83 | | |
84 | 0 | case E_Q_INV_CHAR: |
85 | 0 | error_txt = "Invalid character in q parameter"; |
86 | 0 | *sip_error = -E_BAD_REQ; |
87 | 0 | break; |
88 | | |
89 | 0 | case E_Q_EMPTY: |
90 | 0 | error_txt = "Empty q parameter"; |
91 | 0 | *sip_error = -E_BAD_REQ; |
92 | 0 | break; |
93 | 0 | ; |
94 | |
|
95 | 0 | case E_Q_TOO_BIG: |
96 | 0 | error_txt = "Q parameter too big"; |
97 | 0 | *sip_error = -E_BAD_REQ; |
98 | 0 | break; |
99 | | |
100 | 0 | case E_Q_DEC_MISSING: |
101 | 0 | error_txt = "Decimal part missing in q"; |
102 | 0 | *sip_error = -E_BAD_REQ; |
103 | 0 | break; |
104 | | |
105 | 0 | case E_CANCELED: |
106 | 0 | error_txt = "Transaction canceled"; |
107 | 0 | *sip_error = -int_error; |
108 | 0 | break; |
109 | | |
110 | 0 | case E_OUT_OF_MEM: |
111 | 0 | error_txt = "Message processing error"; |
112 | 0 | *sip_error = 500; |
113 | 0 | break; |
114 | | |
115 | 0 | case E_UNEXPECTED_STATE: |
116 | 0 | error_txt = "Internal processing error"; |
117 | 0 | *sip_error = 500; |
118 | 0 | break; |
119 | | |
120 | 0 | case E_OK: |
121 | 0 | error_txt = "No error"; |
122 | 0 | *sip_error = 500; |
123 | 0 | break; |
124 | | |
125 | 0 | default: |
126 | 0 | error_txt = "I'm terribly sorry, server error occurred"; |
127 | 0 | *sip_error = 500; |
128 | 0 | break; |
129 | 0 | } |
130 | 0 | return snprintf( |
131 | 0 | phrase, etl, "%s (%d/%s)", error_txt, -int_error, signature); |
132 | 0 | } |
133 | | |
134 | | char *error_text(int code) |
135 | 0 | { |
136 | 0 | switch(code) { |
137 | | |
138 | 0 | case 100: |
139 | 0 | return "Trying"; |
140 | 0 | case 180: |
141 | 0 | return "Ringing"; |
142 | 0 | case 181: |
143 | 0 | return "Call Is Being Forwarded"; |
144 | 0 | case 182: |
145 | 0 | return "Queued"; |
146 | 0 | case 183: |
147 | 0 | return "Session Progress"; |
148 | | |
149 | 0 | case 200: |
150 | 0 | return "OK"; |
151 | | |
152 | 0 | case 300: |
153 | 0 | return "Multiple Choices"; |
154 | 0 | case 301: |
155 | 0 | return "Moved Permanently"; |
156 | 0 | case 302: |
157 | 0 | return "Moved Temporarily"; |
158 | 0 | case 305: |
159 | 0 | return "Use Proxy"; |
160 | 0 | case 380: |
161 | 0 | return "Alternative Service"; |
162 | | |
163 | 0 | case 400: |
164 | 0 | return "Bad Request"; |
165 | 0 | case 401: |
166 | 0 | return "Unauthorized"; |
167 | 0 | case 402: |
168 | 0 | return "Payment Required"; |
169 | 0 | case 403: |
170 | 0 | return "Forbidden"; |
171 | 0 | case 404: |
172 | 0 | return "Not Found"; |
173 | 0 | case 405: |
174 | 0 | return "Method Not Allowed"; |
175 | 0 | case 406: |
176 | 0 | return "Not Acceptable"; |
177 | 0 | case 407: |
178 | 0 | return "Proxy Authentication Required"; |
179 | 0 | case 408: |
180 | 0 | return "Request Timeout"; |
181 | 0 | case 410: |
182 | 0 | return "Gone"; |
183 | 0 | case 413: |
184 | 0 | return "Request Entity Too Large"; |
185 | 0 | case 414: |
186 | 0 | return "Request-URI Too Long"; |
187 | 0 | case 415: |
188 | 0 | return "Unsupported Media Type"; |
189 | 0 | case 416: |
190 | 0 | return "Unsupported URI Scheme"; |
191 | 0 | case 417: |
192 | 0 | return "Bad Extension"; |
193 | 0 | case 421: |
194 | 0 | return "Extension Required"; |
195 | 0 | case 423: |
196 | 0 | return "Interval Too Brief"; |
197 | 0 | case 480: |
198 | 0 | return "Temporarily Unavailable"; |
199 | 0 | case 481: |
200 | 0 | return "Call/Transaction Does Not Exist"; |
201 | 0 | case 482: |
202 | 0 | return "Loop Detected"; |
203 | 0 | case 483: |
204 | 0 | return "Too Many Hops"; |
205 | 0 | case 484: |
206 | 0 | return "Address Incomplete"; |
207 | 0 | case 485: |
208 | 0 | return "Ambiguous"; |
209 | 0 | case 486: |
210 | 0 | return "Busy Here"; |
211 | 0 | case 487: |
212 | 0 | return "Request Terminated"; |
213 | 0 | case 488: |
214 | 0 | return "Not Acceptable Here"; |
215 | 0 | case 491: |
216 | 0 | return "Request Pending"; |
217 | | |
218 | 0 | case 500: |
219 | 0 | return "Server Internal Error"; |
220 | 0 | case 501: |
221 | 0 | return "Not Implemented"; |
222 | 0 | case 502: |
223 | 0 | return "Bad Gateway"; |
224 | 0 | case 503: |
225 | 0 | return "Service Unavailable"; |
226 | 0 | case 504: |
227 | 0 | return "Server Time-Out"; |
228 | 0 | case 505: |
229 | 0 | return "Version Not Supported"; |
230 | 0 | case 513: |
231 | 0 | return "Message Too Large"; |
232 | | |
233 | 0 | case 600: |
234 | 0 | return "Busy Everywhere"; |
235 | 0 | case 603: |
236 | 0 | return "Decline"; |
237 | 0 | case 604: |
238 | 0 | return "Does Not Exist Anywhere"; |
239 | 0 | case 606: |
240 | 0 | return "Not Acceptable"; |
241 | 0 | } |
242 | | |
243 | 0 | if(code >= 600) |
244 | 0 | return "Global Failure"; |
245 | 0 | else if(code >= 500) |
246 | 0 | return "Server Failure"; |
247 | 0 | else if(code >= 400) |
248 | 0 | return "Request Failure"; |
249 | 0 | else if(code >= 300) |
250 | 0 | return "Redirection"; |
251 | 0 | else if(code >= 200) |
252 | 0 | return "Successful"; |
253 | 0 | else if(code >= 100) |
254 | 0 | return "Provisional"; |
255 | 0 | else |
256 | 0 | return "Unspecified"; |
257 | 0 | } |
258 | | |
259 | | void get_reply_status(str *status, struct sip_msg *reply, int code) |
260 | 0 | { |
261 | 0 | str phrase; |
262 | |
|
263 | 0 | status->s = 0; |
264 | |
|
265 | 0 | if(reply == 0) { |
266 | 0 | LM_CRIT("0 msg\n"); |
267 | 0 | return; |
268 | 0 | } |
269 | | |
270 | 0 | if(reply == FAKED_REPLY) { |
271 | 0 | phrase.s = error_text(code); |
272 | 0 | phrase.len = strlen(phrase.s); |
273 | 0 | } else { |
274 | 0 | phrase = reply->first_line.u.reply.reason; |
275 | 0 | } |
276 | 0 | status->len = phrase.len + 3 /*code*/ + 1 /*space*/; |
277 | 0 | status->s = pkg_malloc(status->len + 1 /*ZT */); |
278 | 0 | if(!status->s) { |
279 | 0 | PKG_MEM_ERROR; |
280 | 0 | return; |
281 | 0 | } |
282 | 0 | status->s[3] = ' '; |
283 | 0 | status->s[2] = '0' + code % 10; |
284 | 0 | code = code / 10; |
285 | 0 | status->s[1] = '0' + code % 10; |
286 | 0 | code = code / 10; |
287 | 0 | status->s[0] = '0' + code % 10; |
288 | 0 | memcpy(&status->s[4], phrase.s, phrase.len); |
289 | 0 | status->s[status->len] = 0; |
290 | 0 | } |