atomic "new_tran" construct; it returns: <0 on error +1 if a request did not match a transaction - it that was an ack, the calling function shall forward statelessly - otherwise it means, a new transaction was introduced and the calling function shall reply/relay/whatever_appropriate 0 on retransmission */
| 1030 | 0 on retransmission |
| 1031 | */ |
| 1032 | int t_newtran( struct sip_msg* p_msg, int full_uas ) |
| 1033 | { |
| 1034 | int lret, my_err; |
| 1035 | context_p ctx_backup; |
| 1036 | |
| 1037 | /* is T still up-to-date ? */ |
| 1038 | LM_DBG("transaction on entrance=%p\n",T); |
| 1039 | |
| 1040 | if ( T && T!=T_UNDEFINED ) { |
| 1041 | LM_DBG("transaction already in process %p\n", T ); |
| 1042 | return E_SCRIPT; |
| 1043 | } |
| 1044 | |
| 1045 | T = T_UNDEFINED; |
| 1046 | /* first of all, parse everything -- we will store in shared memory |
| 1047 | and need to have all headers ready for generating potential replies |
| 1048 | later; parsing later on demand is not an option since the request |
| 1049 | will be in shmem and applying parse_headers to it would intermix |
| 1050 | shmem with pkg_mem |
| 1051 | */ |
| 1052 | |
| 1053 | if (parse_headers(p_msg, HDR_EOH_F, 0 )<0) { |
| 1054 | LM_ERR("parse_headers failed\n"); |
| 1055 | return E_BAD_REQ; |
| 1056 | } |
| 1057 | if ((p_msg->parsed_flag & HDR_EOH_F)!=HDR_EOH_F) { |
| 1058 | LM_ERR("EoH not parsed\n"); |
| 1059 | return E_OUT_OF_MEM; |
| 1060 | } |
| 1061 | /* t_lookup_requests attempts to find the transaction; |
| 1062 | it also calls check_transaction_quadruple -> it is |
| 1063 | safe to assume we have from/callid/cseq/to |
| 1064 | */ |
| 1065 | lret = t_lookup_request( p_msg, 1 /* leave locked if not found */ ); |
| 1066 | |
| 1067 | /* on error, pass the error in the stack ... nothing is locked yet |
| 1068 | if 0 is returned */ |
| 1069 | if (lret==0) return E_BAD_TUPEL; |
| 1070 | |
| 1071 | /* transaction found, it's a retransmission */ |
| 1072 | if (lret>0) { |
| 1073 | if (p_msg->REQ_METHOD==METHOD_ACK) { |
| 1074 | t_release_transaction(T); |
| 1075 | } else { |
| 1076 | t_retransmit_reply(T); |
| 1077 | } |
| 1078 | /* hide the transaction from the upper layer */ |
| 1079 | t_unref( p_msg ); |
| 1080 | /* things are done -- return from script */ |
| 1081 | return 0; |
| 1082 | } |
| 1083 | |
| 1084 | /* from now on, be careful -- hash table is locked */ |
| 1085 | |
| 1086 | if (lret==-2) { /* was it an e2e ACK ? if so, trigger a callback */ |
| 1087 | if (e2eack_T->relaied_reply_branch==-2) { |
| 1088 | /* if a ACK for a local replied transaction, release the |
| 1089 | INVITE transaction and break the script -> simply absorb |
no test coverage detected