Ignore:
Timestamp:
Sep 4, 2013 10:07:45 AM (9 years ago)
Author:
ming
Message:

Closed #1696: IP change detection (Contact rewrite method) based on REGISTER final response

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c

    r4548 r4586  
    7676    void                        *token; 
    7777    pjsip_regc_cb               *cb; 
     78    pjsip_regc_tsx_cb           *tsx_cb; 
    7879 
    7980    pj_str_t                     str_srv_url; 
     
    728729} 
    729730 
     731static void cbparam_init( struct pjsip_regc_cbparam *cbparam, 
     732                          pjsip_regc *regc,  
     733                          pj_status_t status, int st_code,  
     734                          const pj_str_t *reason, 
     735                          pjsip_rx_data *rdata, pj_int32_t expiration, 
     736                          int contact_cnt, pjsip_contact_hdr *contact[]) 
     737{ 
     738    cbparam->regc = regc; 
     739    cbparam->token = regc->token; 
     740    cbparam->status = status; 
     741    cbparam->code = st_code; 
     742    cbparam->reason = *reason; 
     743    cbparam->rdata = rdata; 
     744    cbparam->contact_cnt = contact_cnt; 
     745    cbparam->expiration = expiration; 
     746    if (contact_cnt) { 
     747        pj_memcpy( cbparam->contact, contact,  
     748                   contact_cnt*sizeof(pjsip_contact_hdr*)); 
     749    } 
     750} 
    730751 
    731752static void call_callback(pjsip_regc *regc, pj_status_t status, int st_code,  
     
    736757    struct pjsip_regc_cbparam cbparam; 
    737758 
    738  
    739759    if (!regc->cb) 
    740760        return; 
    741761 
    742     cbparam.regc = regc; 
    743     cbparam.token = regc->token; 
    744     cbparam.status = status; 
    745     cbparam.code = st_code; 
    746     cbparam.reason = *reason; 
    747     cbparam.rdata = rdata; 
    748     cbparam.contact_cnt = contact_cnt; 
    749     cbparam.expiration = expiration; 
    750     if (contact_cnt) { 
    751         pj_memcpy( cbparam.contact, contact,  
    752                    contact_cnt*sizeof(pjsip_contact_hdr*)); 
    753     } 
    754  
     762    cbparam_init(&cbparam, regc, status, st_code, reason, rdata, expiration, 
     763                 contact_cnt, contact); 
    755764    (*regc->cb)(&cbparam); 
    756765} 
     
    813822    } 
    814823} 
     824 
     825PJ_DEF(pj_status_t) pjsip_regc_set_reg_tsx_cb( pjsip_regc *regc, 
     826                                               pjsip_regc_tsx_cb *tsx_cb) 
     827{ 
     828    PJ_ASSERT_RETURN(regc, PJ_EINVAL); 
     829    regc->tsx_cb = tsx_cb; 
     830    return PJ_SUCCESS; 
     831} 
     832 
    815833 
    816834PJ_DEF(pj_status_t) pjsip_regc_set_via_sent_by( pjsip_regc *regc, 
     
    10361054    pjsip_transaction *tsx = event->body.tsx_state.tsx; 
    10371055    pj_bool_t handled = PJ_TRUE; 
     1056    pj_bool_t update_contact = PJ_FALSE; 
    10381057 
    10391058    pj_atomic_inc(regc->busy_ctr); 
     
    10551074            pjsip_transport_add_ref(regc->last_transport); 
    10561075        } 
     1076    } 
     1077 
     1078    if (regc->_delete_flag == 0 && regc->tsx_cb && 
     1079        regc->current_op == REGC_REGISTERING) 
     1080    { 
     1081        struct pjsip_regc_tsx_cb_param param; 
     1082 
     1083        param.contact_cnt = -1; 
     1084        cbparam_init(&param.cbparam, regc, PJ_SUCCESS, tsx->status_code, 
     1085                     &tsx->status_text, 
     1086                     (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ?  
     1087                      event->body.tsx_state.src.rdata : NULL, 
     1088                     -1, 0, NULL); 
     1089 
     1090        /* Call regc tsx callback before handling any response */ 
     1091        pj_lock_release(regc->lock); 
     1092        (*regc->tsx_cb)(&param); 
     1093        pj_lock_acquire(regc->lock); 
     1094 
     1095        if (param.contact_cnt >= 0) { 
     1096            /* Since we receive non-2xx response, it means that (some) contact 
     1097             * bindings haven't been established so we can safely remove these 
     1098             * contact headers. This is to avoid removing non-existent contact 
     1099             * bindings later. 
     1100             */ 
     1101            if (tsx->status_code/100 != 2) { 
     1102                pjsip_contact_hdr *h; 
     1103 
     1104                h = regc->contact_hdr_list.next; 
     1105                while (h != &regc->contact_hdr_list) { 
     1106                    pjsip_contact_hdr *next = h->next; 
     1107 
     1108                    if (h->expires == -1) { 
     1109                        pj_list_erase(h); 
     1110                    } 
     1111                    h = next; 
     1112                } 
     1113            } 
     1114 
     1115            /* Update contact address */ 
     1116            pjsip_regc_update_contact(regc, param.contact_cnt, param.contact); 
     1117            update_contact = PJ_TRUE; 
     1118        } 
    10571119    } 
    10581120 
     
    10671129        regc->current_op = REGC_IDLE; 
    10681130 
    1069         status = pjsip_auth_clt_reinit_req( &regc->auth_sess, 
     1131        if (update_contact) { 
     1132            pjsip_msg *msg; 
     1133            pjsip_hdr *hdr, *ins_hdr; 
     1134            pjsip_contact_hdr *chdr; 
     1135 
     1136            /* Delete Contact headers, but we shouldn't delete headers 
     1137             * which are supposed to remove contact bindings since 
     1138             * we cannot reconstruct those headers. 
     1139             */ 
     1140            msg = tsx->last_tx->msg; 
     1141            hdr = msg->hdr.next; 
     1142            ins_hdr = &msg->hdr; 
     1143            while (hdr != &msg->hdr) { 
     1144                pjsip_hdr *next = hdr->next; 
     1145 
     1146                if (hdr->type == PJSIP_H_CONTACT) { 
     1147                    chdr = (pjsip_contact_hdr *)hdr; 
     1148                    if (chdr->expires != 0) { 
     1149                        pj_list_erase(hdr); 
     1150                        ins_hdr = next; 
     1151                    } 
     1152                } 
     1153                hdr = next; 
     1154            } 
     1155 
     1156            /* Add Contact headers. */ 
     1157            chdr = regc->contact_hdr_list.next; 
     1158            while (chdr != &regc->contact_hdr_list) { 
     1159                pj_list_insert_before(ins_hdr, (pjsip_hdr*) 
     1160                    pjsip_hdr_shallow_clone(tsx->last_tx->pool, chdr)); 
     1161                chdr = chdr->next; 
     1162            } 
     1163 
     1164            /* Also add bindings which are to be removed */ 
     1165            while (!pj_list_empty(&regc->removed_contact_hdr_list)) { 
     1166                chdr = regc->removed_contact_hdr_list.next; 
     1167                pj_list_insert_before(ins_hdr, (pjsip_hdr*) 
     1168                    pjsip_hdr_clone(tsx->last_tx->pool, chdr)); 
     1169                pj_list_erase(chdr); 
     1170            } 
     1171        } 
     1172 
     1173        status = pjsip_auth_clt_reinit_req( &regc->auth_sess, 
    10701174                                            rdata,  
    10711175                                            tsx->last_tx,   
Note: See TracChangeset for help on using the changeset viewer.