| 298 | */ |
| 299 | |
| 300 | static int matching_3261( struct sip_msg *p_msg, struct cell **trans, |
| 301 | enum request_method skip_method) |
| 302 | { |
| 303 | struct cell *p_cell; |
| 304 | struct sip_msg *t_msg; |
| 305 | struct via_body *via1; |
| 306 | int is_ack; |
| 307 | int dlg_parsed; |
| 308 | int ret = 0; |
| 309 | struct cell *e2e_ack_trans; |
| 310 | |
| 311 | e2e_ack_trans=0; |
| 312 | via1=p_msg->via1; |
| 313 | is_ack=p_msg->REQ_METHOD==METHOD_ACK; |
| 314 | dlg_parsed=0; |
| 315 | /* update parsed tid */ |
| 316 | via1->tid.s=via1->branch->value.s+MCOOKIE_LEN; |
| 317 | via1->tid.len=via1->branch->value.len-MCOOKIE_LEN; |
| 318 | |
| 319 | for ( p_cell = get_tm_table()->entrys[p_msg->hash_index].first_cell; |
| 320 | p_cell; p_cell = p_cell->next_cell ) |
| 321 | { |
| 322 | t_msg=p_cell->uas.request; |
| 323 | /* don't try matching UAC transactions */ |
| 324 | if (is_local(p_cell) || !t_msg) continue; |
| 325 | if (skip_method & t_msg->REQ_METHOD) continue; |
| 326 | |
| 327 | /* here we do an exercise which will be removed from future code |
| 328 | * versions: we try to match end-2-end ACKs if they appear at our |
| 329 | * server. This allows some applications bound to TM via callbacks |
| 330 | * to correlate the e2e ACKs with transaction context, e.g., for |
| 331 | * purpose of accounting. We think it is a bad place here, among |
| 332 | * other things because it is not reliable. If a transaction loops |
| 333 | * via OpenSIPS the ACK can't be matched to proper INVITE transaction |
| 334 | * (it is a separate transactino with its own branch ID) and it |
| 335 | * matches all transaction instances in the loop dialog-wise. |
| 336 | * Eventually, regardless to which transaction in the loop the |
| 337 | * ACK belongs, only the first one will match. |
| 338 | */ |
| 339 | |
| 340 | /* dialog matching needs to be applied for ACK/200s */ |
| 341 | if (is_ack && e2e_ack_trans==0 && |
| 342 | p_cell->uas.status>=200 && p_cell->uas.status<300) { |
| 343 | /* make sure we have parsed all things we need for dialog |
| 344 | * matching */ |
| 345 | if (!dlg_parsed) { |
| 346 | dlg_parsed=1; |
| 347 | if (!parse_dlg(p_msg)) { |
| 348 | LM_ERR("dlg parsing failed\n"); |
| 349 | return 0; |
| 350 | } |
| 351 | } |
| 352 | ret=ack_matching(p_cell /* t w/invite */, p_msg /* ack */); |
| 353 | if (ret>0) { |
| 354 | e2e_ack_trans=p_cell; |
| 355 | continue; |
| 356 | } |
| 357 | /* this ACK is neither local "negative" one, nor a proxied |
no test coverage detected