| File: | root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/stun/stun_server_ctx.cpp |
| Warning: | line 382, column 10 Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* |
| 2 | Copyright (c) 2007, Adobe Systems, Incorporated |
| 3 | All rights reserved. |
| 4 | |
| 5 | Redistribution and use in source and binary forms, with or without |
| 6 | modification, are permitted provided that the following conditions are |
| 7 | met: |
| 8 | |
| 9 | * Redistributions of source code must retain the above copyright |
| 10 | notice, this list of conditions and the following disclaimer. |
| 11 | |
| 12 | * Redistributions in binary form must reproduce the above copyright |
| 13 | notice, this list of conditions and the following disclaimer in the |
| 14 | documentation and/or other materials provided with the distribution. |
| 15 | |
| 16 | * Neither the name of Adobe Systems, Network Resonance nor the names of its |
| 17 | contributors may be used to endorse or promote products derived from |
| 18 | this software without specific prior written permission. |
| 19 | |
| 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | */ |
| 32 | |
| 33 | #include <string.h> |
| 34 | #include <assert.h> |
| 35 | |
| 36 | #include "nr_api.h" |
| 37 | #include "stun.h" |
| 38 | |
| 39 | static int nr_stun_server_destroy_client(nr_stun_server_client *clnt); |
| 40 | static int nr_stun_server_send_response(nr_stun_server_ctx *ctx, nr_socket *sock, nr_transport_addr *peer_addr, nr_stun_message *res, nr_stun_server_client *clnt); |
| 41 | static int nr_stun_server_process_request_auth_checks(nr_stun_server_ctx *ctx, nr_stun_message *req, int auth_rule, nr_stun_message *res); |
| 42 | |
| 43 | |
| 44 | int nr_stun_server_ctx_create(char *label, nr_stun_server_ctx **ctxp) |
| 45 | { |
| 46 | int r,_status; |
| 47 | nr_stun_server_ctx *ctx=0; |
| 48 | |
| 49 | if ((r=nr_stun_startup())) |
| 50 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 51 | |
| 52 | if(!(ctx=R_NEW(nr_stun_server_ctx)(nr_stun_server_ctx*)calloc(1,sizeof(nr_stun_server_ctx)))) |
| 53 | ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 54 | |
| 55 | if(!(ctx->label=strdup(label))) |
| 56 | ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 57 | |
| 58 | STAILQ_INIT(&ctx->clients)do { (((&ctx->clients))->stqh_first) = __null; (& ctx->clients)->stqh_last = &(((&ctx->clients ))->stqh_first); } while (0); |
| 59 | |
| 60 | *ctxp=ctx; |
| 61 | |
| 62 | _status=0; |
| 63 | abort: |
| 64 | return(_status); |
| 65 | } |
| 66 | |
| 67 | int nr_stun_server_ctx_destroy(nr_stun_server_ctx **ctxp) |
| 68 | { |
| 69 | nr_stun_server_ctx *ctx; |
| 70 | nr_stun_server_client *clnt1,*clnt2; |
| 71 | |
| 72 | if(!ctxp || !*ctxp) |
| 73 | return(0); |
| 74 | |
| 75 | ctx=*ctxp; |
| 76 | |
| 77 | STAILQ_FOREACH_SAFE(clnt1, &ctx->clients, entry, clnt2)for ((clnt1) = (((&ctx->clients))->stqh_first); (clnt1 ) && ((clnt2) = (((clnt1))->entry.stqe_next), 1); ( clnt1) = (clnt2)) { |
| 78 | nr_stun_server_destroy_client(clnt1); |
| 79 | } |
| 80 | |
| 81 | nr_stun_server_destroy_client(ctx->default_client); |
| 82 | |
| 83 | free(ctx->label); |
| 84 | free(ctx); |
| 85 | |
| 86 | return(0); |
| 87 | } |
| 88 | |
| 89 | static int nr_stun_server_client_create(nr_stun_server_ctx *ctx, const char *client_label, char *user, Data *pass, nr_stun_server_cb cb, void *cb_arg, nr_stun_server_client **clntp) |
| 90 | { |
| 91 | nr_stun_server_client *clnt=0; |
| 92 | int r,_status; |
| 93 | |
| 94 | if(!(clnt=R_NEW(nr_stun_server_client)(nr_stun_server_client*)calloc(1,sizeof(nr_stun_server_client )))) |
| 95 | ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 96 | |
| 97 | if(!(clnt->label=strdup(client_label))) |
| 98 | ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 99 | |
| 100 | if(!(clnt->username=strdup(user))) |
| 101 | ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 102 | |
| 103 | if(r=r_data_copy(&clnt->password,pass)) |
| 104 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 105 | |
| 106 | r_log(NR_LOG_STUN,LOG_DEBUG7,"STUN-SERVER(%s)/CLIENT(%s): Adding client for %s",ctx->label, client_label, user); |
| 107 | clnt->stun_server_cb=cb; |
| 108 | clnt->cb_arg=cb_arg; |
| 109 | |
| 110 | *clntp = clnt; |
| 111 | _status=0; |
| 112 | abort: |
| 113 | if(_status){ |
| 114 | nr_stun_server_destroy_client(clnt); |
| 115 | } |
| 116 | return(_status); |
| 117 | } |
| 118 | |
| 119 | int nr_stun_server_add_client(nr_stun_server_ctx *ctx, char *client_label, char *user, Data *pass, nr_stun_server_cb cb, void *cb_arg) |
| 120 | { |
| 121 | int r,_status; |
| 122 | nr_stun_server_client *clnt; |
| 123 | |
| 124 | if (r=nr_stun_server_client_create(ctx, client_label, user, pass, cb, cb_arg, &clnt)) |
| 125 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 126 | |
| 127 | STAILQ_INSERT_TAIL(&ctx->clients,clnt,entry)do { (((clnt))->entry.stqe_next) = __null; *(&ctx-> clients)->stqh_last = (clnt); (&ctx->clients)->stqh_last = &(((clnt))->entry.stqe_next); } while (0); |
| 128 | |
| 129 | _status=0; |
| 130 | abort: |
| 131 | return(_status); |
| 132 | } |
| 133 | |
| 134 | int nr_stun_server_add_default_client(nr_stun_server_ctx *ctx, char *ufrag, Data *pass, nr_stun_server_cb cb, void *cb_arg) |
| 135 | { |
| 136 | int r,_status; |
| 137 | nr_stun_server_client *clnt; |
| 138 | |
| 139 | assert(!ctx->default_client)(static_cast <bool> (!ctx->default_client) ? void (0 ) : __assert_fail ("!ctx->default_client", __builtin_FILE ( ), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); |
| 140 | if (ctx->default_client) |
| 141 | ABORT(R_INTERNAL)do { int _r=3; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 142 | |
| 143 | if (r=nr_stun_server_client_create(ctx, "default_client", ufrag, pass, cb, cb_arg, &clnt)) |
| 144 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 145 | |
| 146 | ctx->default_client = clnt; |
| 147 | |
| 148 | _status=0; |
| 149 | abort: |
| 150 | return(_status); |
| 151 | } |
| 152 | |
| 153 | int nr_stun_server_remove_client(nr_stun_server_ctx *ctx, void *cb_arg) |
| 154 | { |
| 155 | nr_stun_server_client *clnt1,*clnt2; |
| 156 | int found = 0; |
| 157 | |
| 158 | STAILQ_FOREACH_SAFE(clnt1, &ctx->clients, entry, clnt2)for ((clnt1) = (((&ctx->clients))->stqh_first); (clnt1 ) && ((clnt2) = (((clnt1))->entry.stqe_next), 1); ( clnt1) = (clnt2)) { |
| 159 | if(clnt1->cb_arg == cb_arg) { |
| 160 | STAILQ_REMOVE(&ctx->clients, clnt1, nr_stun_server_client_, entry)do { if ((((&ctx->clients))->stqh_first) == (clnt1) ) { do { if ((((((&ctx->clients)))->stqh_first) = ( (((((&ctx->clients)))->stqh_first))->entry.stqe_next )) == __null) ((&ctx->clients))->stqh_last = &( (((&ctx->clients)))->stqh_first); } while (0); } else { struct nr_stun_server_client_ *curelm = (((&ctx->clients ))->stqh_first); while (((curelm)->entry.stqe_next) != ( clnt1)) curelm = ((curelm)->entry.stqe_next); if ((((curelm )->entry.stqe_next) = ((((curelm)->entry.stqe_next))-> entry.stqe_next)) == __null) (&ctx->clients)->stqh_last = &(((curelm))->entry.stqe_next); } } while (0); |
| 161 | nr_stun_server_destroy_client(clnt1); |
| 162 | found++; |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | if (!found) |
| 167 | ERETURN(R_NOT_FOUND)do {int _r=2; if(!_r) _r=-1; return(_r);} while(0); |
| 168 | |
| 169 | return 0; |
| 170 | } |
| 171 | |
| 172 | static int nr_stun_server_get_password(void *arg, nr_stun_message *msg, Data **password) |
| 173 | { |
| 174 | int _status; |
| 175 | nr_stun_server_ctx *ctx = (nr_stun_server_ctx*)arg; |
| 176 | nr_stun_server_client *clnt = 0; |
| 177 | nr_stun_message_attribute *username_attribute; |
| 178 | |
| 179 | if ((nr_stun_get_message_client(ctx, msg, &clnt))) { |
| 180 | if (! nr_stun_message_has_attribute(msg, NR_STUN_ATTR_USERNAME0x0006, &username_attribute)) { |
| 181 | r_log(NR_LOG_STUN,LOG_WARNING4,"STUN-SERVER(%s): Missing Username",ctx->label); |
| 182 | ABORT(R_NOT_FOUND)do { int _r=2; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 183 | } |
| 184 | |
| 185 | /* Although this is an exceptional condition, we'll already have seen a |
| 186 | * NOTICE-level log message about the unknown user, so additional log |
| 187 | * messages at any level higher than DEBUG are unnecessary. */ |
| 188 | |
| 189 | r_log(NR_LOG_STUN,LOG_DEBUG7,"STUN-SERVER(%s): Unable to find password for unknown user: %s",ctx->label,username_attribute->u.username); |
| 190 | ABORT(R_NOT_FOUND)do { int _r=2; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 191 | } |
| 192 | |
| 193 | *password = &clnt->password; |
| 194 | |
| 195 | _status=0; |
| 196 | abort: |
| 197 | return(_status); |
| 198 | } |
| 199 | |
| 200 | int nr_stun_server_process_request_auth_checks(nr_stun_server_ctx *ctx, nr_stun_message *req, int auth_rule, nr_stun_message *res) |
| 201 | { |
| 202 | int r,_status; |
| 203 | |
| 204 | if (nr_stun_message_has_attribute(req, NR_STUN_ATTR_MESSAGE_INTEGRITY0x0008, 0) |
| 205 | || !(auth_rule & NR_STUN_AUTH_RULE_OPTIONAL(1<<0))) { |
| 206 | /* favor long term credentials over short term, if both are supported */ |
| 207 | |
| 208 | if (auth_rule & NR_STUN_AUTH_RULE_LONG_TERM(1<<9)) { |
| 209 | if ((r=nr_stun_receive_request_long_term_auth(req, ctx, res))) |
| 210 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 211 | } |
| 212 | else if (auth_rule & NR_STUN_AUTH_RULE_SHORT_TERM(1<<8)) { |
| 213 | if ((r=nr_stun_receive_request_or_indication_short_term_auth(req, res))) |
| 214 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | _status=0; |
| 219 | abort: |
| 220 | return(_status); |
| 221 | } |
| 222 | |
| 223 | int nr_stun_server_process_request(nr_stun_server_ctx *ctx, nr_socket *sock, char *msg, int len, nr_transport_addr *peer_addr, int auth_rule) |
| 224 | { |
| 225 | int r,_status; |
| 226 | char string[256]; |
| 227 | nr_stun_message *req = 0; |
| 228 | nr_stun_message *res = 0; |
| 229 | nr_stun_server_client *clnt = 0; |
| 230 | nr_stun_server_request info; |
| 231 | int error; |
| 232 | int dont_free = 0; |
| 233 | nr_transport_addr my_addr; |
| 234 | |
| 235 | if ((r=nr_socket_getaddr(sock, &my_addr))) { |
| 236 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 237 | } |
| 238 | |
| 239 | r_log(NR_LOG_STUN,LOG_DEBUG7,"STUN-SERVER(%s): Received(my_addr=%s,peer_addr=%s)",ctx->label,my_addr.as_string,peer_addr->as_string); |
| 240 | |
| 241 | snprintf(string, sizeof(string)-1, "STUN-SERVER(%s): Received ", ctx->label); |
| 242 | r_dump(NR_LOG_STUN, LOG_DEBUG7, string, (char*)msg, len); |
| 243 | |
| 244 | memset(&info,0,sizeof(info)); |
| 245 | |
| 246 | if ((r=nr_stun_message_create2(&req, (UCHAR*)msg, len))) |
| 247 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 248 | |
| 249 | if ((r=nr_stun_message_create(&res))) |
| 250 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 251 | |
| 252 | if ((r=nr_stun_decode_message(req, nr_stun_server_get_password, ctx))) { |
| 253 | /* RFC5389 S 7.3 says "If any errors are detected, the message is |
| 254 | * silently discarded." */ |
| 255 | #ifndef USE_STUN_PEDANTIC1 |
| 256 | /* ... but that seems like a bad idea, at least return a 400 so |
| 257 | * that the server isn't a black hole to the client */ |
| 258 | nr_stun_form_error_response(req, res, 400, "Bad Request - Failed to decode request"); |
| 259 | ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 260 | #endif /* USE_STUN_PEDANTIC */ |
| 261 | ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while (0); |
| 262 | } |
| 263 | |
| 264 | if ((r=nr_stun_receive_message(0, req))) { |
| 265 | /* RFC5389 S 7.3 says "If any errors are detected, the message is |
| 266 | * silently discarded." */ |
| 267 | #ifndef USE_STUN_PEDANTIC1 |
| 268 | /* ... but that seems like a bad idea, at least return a 400 so |
| 269 | * that the server isn't a black hole to the client */ |
| 270 | nr_stun_form_error_response(req, res, 400, "Bad Request - Section 7.3 check failed"); |
| 271 | ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 272 | #endif /* USE_STUN_PEDANTIC */ |
| 273 | ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while (0); |
| 274 | } |
| 275 | |
| 276 | if (NR_STUN_GET_TYPE_CLASS(req->header.type)((((req->header.type) >> 7) & 0x002) | (((req-> header.type) >> 4) & 0x001)) != NR_CLASS_REQUEST0x0 |
| 277 | && NR_STUN_GET_TYPE_CLASS(req->header.type)((((req->header.type) >> 7) & 0x002) | (((req-> header.type) >> 4) & 0x001)) != NR_CLASS_INDICATION0x1) { |
| 278 | r_log(NR_LOG_STUN,LOG_WARNING4,"STUN-SERVER(%s): Illegal message type: %04x",ctx->label,req->header.type); |
| 279 | /* RFC5389 S 7.3 says "If any errors are detected, the message is |
| 280 | * silently discarded." */ |
| 281 | #ifndef USE_STUN_PEDANTIC1 |
| 282 | /* ... but that seems like a bad idea, at least return a 400 so |
| 283 | * that the server isn't a black hole to the client */ |
| 284 | nr_stun_form_error_response(req, res, 400, "Bad Request - Unsupported message type"); |
| 285 | ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 286 | #endif /* USE_STUN_PEDANTIC */ |
| 287 | ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while (0); |
| 288 | } |
| 289 | |
| 290 | /* "The STUN agent then does any checks that are required by a |
| 291 | * authentication mechanism that the usage has specified" */ |
| 292 | if ((r=nr_stun_server_process_request_auth_checks(ctx, req, auth_rule, res))) |
| 293 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 294 | |
| 295 | if (NR_STUN_GET_TYPE_CLASS(req->header.type)((((req->header.type) >> 7) & 0x002) | (((req-> header.type) >> 4) & 0x001)) == NR_CLASS_INDICATION0x1) { |
| 296 | if ((r=nr_stun_process_indication(req))) |
| 297 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 298 | } |
| 299 | else { |
| 300 | if ((r=nr_stun_process_request(req, res))) |
| 301 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 302 | } |
| 303 | |
| 304 | assert(res->header.type == 0)(static_cast <bool> (res->header.type == 0) ? void ( 0) : __assert_fail ("res->header.type == 0", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); |
| 305 | |
| 306 | clnt = 0; |
| 307 | if (NR_STUN_GET_TYPE_CLASS(req->header.type)((((req->header.type) >> 7) & 0x002) | (((req-> header.type) >> 4) & 0x001)) == NR_CLASS_REQUEST0x0) { |
| 308 | if ((nr_stun_get_message_client(ctx, req, &clnt))) { |
| 309 | if ((r=nr_stun_form_success_response(req, peer_addr, 0, res))) |
| 310 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 311 | } |
| 312 | else { |
| 313 | if ((r=nr_stun_form_success_response(req, peer_addr, &clnt->password, res))) |
| 314 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | if(clnt && clnt->stun_server_cb){ |
| 319 | r_log(NR_LOG_STUN,LOG_DEBUG7,"Entering STUN server callback"); |
| 320 | |
| 321 | /* Set up the info */ |
| 322 | if(r=nr_transport_addr_copy(&info.src_addr,peer_addr)) |
| 323 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 324 | |
| 325 | info.request = req; |
| 326 | info.response = res; |
| 327 | |
| 328 | error = 0; |
| 329 | dont_free = 0; |
| 330 | if (clnt->stun_server_cb(clnt->cb_arg,ctx,sock,&info,&dont_free,&error)) { |
| 331 | if (error == 0) |
| 332 | error = 500; |
| 333 | |
| 334 | nr_stun_form_error_response(req, res, error, "ICE Failure"); |
| 335 | ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | _status=0; |
| 340 | abort: |
| 341 | if (!res) |
| 342 | goto skip_response; |
| 343 | |
| 344 | if (NR_STUN_GET_TYPE_CLASS(req->header.type)((((req->header.type) >> 7) & 0x002) | (((req-> header.type) >> 4) & 0x001)) == NR_CLASS_INDICATION0x1) |
| 345 | goto skip_response; |
| 346 | |
| 347 | /* Now respond */ |
| 348 | |
| 349 | if (_status != 0 && ! nr_stun_message_has_attribute(res, NR_STUN_ATTR_ERROR_CODE0x0009, 0)) |
| 350 | nr_stun_form_error_response(req, res, 500, "Failed to specify error"); |
| 351 | |
| 352 | if ((r=nr_stun_server_send_response(ctx, sock, peer_addr, res, clnt))) { |
| 353 | r_log(NR_LOG_STUN,LOG_ERR3,"STUN-SERVER(label=%s): Failed sending response (my_addr=%s,peer_addr=%s)",ctx->label,my_addr.as_string,peer_addr->as_string); |
| 354 | _status = R_FAILED10; |
| 355 | } |
| 356 | |
| 357 | if (0) { |
| 358 | skip_response: |
| 359 | _status = 0; |
| 360 | } |
| 361 | |
| 362 | if (!dont_free) { |
| 363 | nr_stun_message_destroy(&res); |
| 364 | nr_stun_message_destroy(&req); |
| 365 | } |
| 366 | |
| 367 | return(_status); |
| 368 | } |
| 369 | |
| 370 | static int nr_stun_server_send_response(nr_stun_server_ctx *ctx, nr_socket *sock, nr_transport_addr *peer_addr, nr_stun_message *res, nr_stun_server_client *clnt) |
| 371 | { |
| 372 | int r,_status; |
| 373 | char string[256]; |
| 374 | nr_transport_addr my_addr; |
| 375 | |
| 376 | if ((r=nr_socket_getaddr(sock, &my_addr))) { |
| 377 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 378 | } |
| 379 | |
| 380 | r_log(NR_LOG_STUN,LOG_DEBUG7,"STUN-SERVER(label=%s): Sending(my_addr=%s,peer_addr=%s)",ctx->label,my_addr.as_string,peer_addr->as_string); |
| 381 | |
| 382 | if ((r=nr_stun_encode_message(res))) { |
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r' | |
| 383 | /* should never happen */ |
| 384 | r_log(NR_LOG_STUN,LOG_ERR3,"STUN-SERVER(label=%s): Unable to encode message", ctx->label); |
| 385 | } |
| 386 | else { |
| 387 | snprintf(string, sizeof(string)-1, "STUN(%s): Sending to %s ", ctx->label, peer_addr->as_string); |
| 388 | r_dump(NR_LOG_STUN, LOG_DEBUG7, string, (char*)res->buffer, res->length); |
| 389 | |
| 390 | if(r=nr_socket_sendto(sock,res->buffer,res->length,0,peer_addr)) |
| 391 | ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 392 | } |
| 393 | |
| 394 | _status=0; |
| 395 | abort: |
| 396 | return(_status); |
| 397 | } |
| 398 | |
| 399 | static int nr_stun_server_destroy_client(nr_stun_server_client *clnt) |
| 400 | { |
| 401 | if (!clnt) |
| 402 | return 0; |
| 403 | |
| 404 | free(clnt->label); |
| 405 | free(clnt->username); |
| 406 | r_data_zfree(&clnt->password); |
| 407 | |
| 408 | free(clnt); |
| 409 | return(0); |
| 410 | } |
| 411 | |
| 412 | int nr_stun_get_message_client(nr_stun_server_ctx *ctx, nr_stun_message *req, nr_stun_server_client **out) |
| 413 | { |
| 414 | int _status; |
| 415 | nr_stun_message_attribute *attr; |
| 416 | nr_stun_server_client *clnt=0; |
| 417 | |
| 418 | if (! nr_stun_message_has_attribute(req, NR_STUN_ATTR_USERNAME0x0006, &attr)) { |
| 419 | r_log(NR_LOG_STUN,LOG_WARNING4,"STUN-SERVER(%s): Missing Username",ctx->label); |
| 420 | ABORT(R_NOT_FOUND)do { int _r=2; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 421 | } |
| 422 | |
| 423 | STAILQ_FOREACH(clnt, &ctx->clients, entry)for((clnt) = (((&ctx->clients))->stqh_first); (clnt ); (clnt) = (((clnt))->entry.stqe_next)) { |
| 424 | if (!strncmp(clnt->username, attr->u.username, |
| 425 | sizeof(attr->u.username))) |
| 426 | break; |
| 427 | } |
| 428 | |
| 429 | if (!clnt && ctx->default_client) { |
| 430 | /* If we can't find a specific client see if this matches the default, |
| 431 | which means that the username starts with our ufrag. |
| 432 | */ |
| 433 | char *colon = strchr(attr->u.username, ':'); |
| 434 | if (colon && !strncmp(ctx->default_client->username, |
| 435 | attr->u.username, |
| 436 | colon - attr->u.username)) { |
| 437 | clnt = ctx->default_client; |
| 438 | r_log(NR_LOG_STUN,LOG_NOTICE5,"STUN-SERVER(%s): Falling back to default client, username=: %s",ctx->label,attr->u.username); |
| 439 | } |
| 440 | } |
| 441 | |
| 442 | if (!clnt) { |
| 443 | r_log(NR_LOG_STUN,LOG_WARNING4,"STUN-SERVER(%s): Request from unknown user: %s",ctx->label,attr->u.username); |
| 444 | ABORT(R_NOT_FOUND)do { int _r=2; if(!_r) _r=-1; _status=_r; goto abort;} while( 0); |
| 445 | } |
| 446 | |
| 447 | *out = clnt; |
| 448 | |
| 449 | _status=0; |
| 450 | abort: |
| 451 | return(_status); |
| 452 | } |
| 453 |