📄 cpl_proxy.h
字号:
if( intr->ip==DEFAULT_ACTION) rez = run_default(intr); else rez = cpl_run_script(intr); switch ( rez ) { case SCRIPT_END: /* we don't need to free the interpreter here since it will * be freed in the final_reply callback */ case SCRIPT_TO_BE_CONTINUED: return; case SCRIPT_RUN_ERROR: case SCRIPT_FORMAT_ERROR: goto exit; default: LOG(L_CRIT,"BUG:cpl-c:failed_reply: improper result %d\n", rez); goto exit; } }exit: /* in case of error the default response chosen by ser at the last * proxying will be forwarded to the UAC */ free_cpl_interpreter( intr ); /* set to zero the param callback*/ *(ps->param) = 0; return;}static inline char *run_proxy( struct cpl_interpreter *intr ){ unsigned short attr_name; unsigned short n; char *kid; char *p; int i; str *s; struct location *loc; int_str tmp; intr->proxy.ordering = PARALLEL_VAL; intr->proxy.recurse = (unsigned short)cpl_env.proxy_recurse; /* identify the attributes */ for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) { get_basic_attr( p, attr_name, n, intr, script_error); switch (attr_name) { case TIMEOUT_ATTR: if (cpl_env.timer_avp.n || cpl_env.timer_avp.s) { tmp.n=(int)n; if ( add_avp( cpl_env.timer_avp_type, cpl_env.timer_avp, tmp)<0) { LOG(L_ERR,"ERROR:run_proxy: unable to set " "timer AVP\n"); /* continue */ } } break; case RECURSE_ATTR: switch (n) { case NO_VAL: intr->proxy.recurse = 0; break; case YES_VAL: /* already set as default */ break; default: LOG(L_ERR,"ERROR:run_proxy: invalid value (%u) found" " for attr. RECURSE in PROXY node!\n",n); goto script_error; } break; case ORDERING_ATTR: if (n!=PARALLEL_VAL && n!=SEQUENTIAL_VAL && n!=FIRSTONLY_VAL){ LOG(L_ERR,"ERROR:run_proxy: invalid value (%u) found" " for attr. ORDERING in PROXY node!\n",n); goto script_error; } intr->proxy.ordering = n; break; default: LOG(L_ERR,"ERROR:run_proxy: unknown attribute (%d) in" "PROXY node\n",attr_name); goto script_error; } } intr->proxy.busy = intr->proxy.noanswer = 0; intr->proxy.redirect = intr->proxy.failure = intr->proxy.default_ = 0; /* this is quite an "expensive" node to run, so let's make some checking * before getting deeply into it */ for( i=0 ; i<NR_OF_KIDS(intr->ip) ; i++ ) { kid = intr->ip + KID_OFFSET(intr->ip,i); check_overflow_by_ptr( kid+SIMPLE_NODE_SIZE(kid), intr, script_error); switch ( NODE_TYPE(kid) ) { case BUSY_NODE : intr->proxy.busy = kid; break; case NOANSWER_NODE: intr->proxy.noanswer = kid; break; case REDIRECTION_NODE: intr->proxy.redirect = kid; break; case FAILURE_NODE: intr->proxy.failure = kid; break; case DEFAULT_NODE: intr->proxy.default_ = kid; break; default: LOG(L_ERR,"ERROR:run_proxy: unknown output node type" " (%d) for PROXY node\n",NODE_TYPE(kid)); goto script_error; } } /* if the location set if empty, I will go directly on failure/default */ if (intr->loc_set==0) { DBG("DEBUG:run_proxy: location set found empty -> going on " "failure/default branch\n"); if (intr->proxy.failure) return get_first_child(intr->proxy.failure); else if (intr->proxy.default_) return get_first_child(intr->proxy.default_); else return DEFAULT_ACTION; } /* if it's the first execution of a proxy node, force parsing of the needed * headers and duplicate them in shared memory */ if (!(intr->flags&CPL_PROXY_DONE)) { /* user name is already in shared memory */ /* requested URI - mandatory in SIP msg (cannot be STR_NOT_FOUND) */ s = GET_RURI( intr->msg ); duplicate_str( s , intr->ruri ); intr->flags |= CPL_RURI_DUPLICATED; /* TO header - mandatory in SIP msg (cannot be STR_NOT_FOUND) */ if (!intr->to) { if (!intr->msg->to && (parse_headers(intr->msg,HDR_TO,0)==-1 || !intr->msg->to)) { LOG(L_ERR,"ERROR:run_proxy: bad msg or missing TO header\n"); goto runtime_error; } s = &(get_to(intr->msg)->uri); } else { s = intr->to; } duplicate_str( s , intr->to ); intr->flags |= CPL_TO_DUPLICATED; /* FROM header - mandatory in SIP msg (cannot be STR_NOT_FOUND) */ if (!intr->from) { if (parse_from_header( intr->msg )==-1) goto runtime_error; s = &(get_from(intr->msg)->uri); } else { s = intr->from; } duplicate_str( s , intr->from ); intr->flags |= CPL_FROM_DUPLICATED; /* SUBJECT header - optional in SIP msg (can be STR_NOT_FOUND) */ if (intr->subject!=STR_NOT_FOUND) { search_and_duplicate_hdr(intr,subject,HDR_SUBJECT,s); if (intr->subject!=STR_NOT_FOUND) intr->flags |= CPL_SUBJECT_DUPLICATED; } /* ORGANIZATION header - optional in SIP msg (can be STR_NOT_FOUND) */ if ( intr->organization!=STR_NOT_FOUND) { search_and_duplicate_hdr(intr,organization,HDR_ORGANIZATION,s); if ( intr->organization!=STR_NOT_FOUND) intr->flags |= CPL_ORGANIZATION_DUPLICATED; } /* USER_AGENT header - optional in SIP msg (can be STR_NOT_FOUND) */ if (intr->user_agent!=STR_NOT_FOUND) { search_and_duplicate_hdr(intr,user_agent,HDR_USERAGENT,s); if (intr->user_agent!=STR_NOT_FOUND) intr->flags |= CPL_USERAGENT_DUPLICATED; } /* ACCEPT_LANGUAGE header - optional in SIP msg * (can be STR_NOT_FOUND) */ if (intr->accept_language!=STR_NOT_FOUND) { search_and_duplicate_hdr(intr,accept_language, HDR_ACCEPTLANGUAGE,s); if (intr->accept_language!=STR_NOT_FOUND) intr->flags |= CPL_ACCEPTLANG_DUPLICATED; } /* PRIORITY header - optional in SIP msg (can be STR_NOT_FOUND) */ if (intr->priority!=STR_NOT_FOUND) { search_and_duplicate_hdr(intr,priority,HDR_PRIORITY,s); if (intr->priority!=STR_NOT_FOUND) intr->flags |= CPL_PRIORITY_DUPLICATED; } /* now is the first time doing proxy, so I can still be stateless; * as proxy is done all the time stateful, I have to switch from * stateless to stateful if necessary. */ if ( !(intr->flags&CPL_IS_STATEFUL) ) { i = cpl_fct.tmb.t_newtran( intr->msg ); if (i<0) { LOG(L_ERR,"ERROR:cpl-c:run_proxy: failed to build new " "transaction!\n"); goto runtime_error; } else if (i==0) { LOG(L_ERR,"ERROR:cpl-c:run_proxy: processed INVITE is a " "retransmission!\n"); /* instead of generating an error is better just to break the * script by returning EO_SCRIPT */ return EO_SCRIPT; } intr->flags |= CPL_IS_STATEFUL; } /* as I am interested in getting the responses back - I need to install * some callback functions for replies */ if (cpl_fct.tmb.register_tmcb(intr->msg,0, TMCB_ON_FAILURE|TMCB_RESPONSE_OUT,reply_callback,(void*)intr) <= 0 ) { LOG(L_ERR, "ERROR:cpl_c:run_proxy: failed to register " "TMCB_RESPONSE_OUT callback\n"); goto runtime_error; } } switch (intr->proxy.ordering) { case FIRSTONLY_VAL: /* forward the request only to the first address from loc. set */ /* location set cannot be empty -> was checked before */ loc = remove_first_location( &(intr->loc_set) ); intr->proxy.last_to_proxy = 0; /* set the new ip before proxy -> otherwise race cond with rpls */ intr->ip = CPL_TO_CONTINUE; if (cpl_proxy_to_loc_set(intr->msg,&loc,intr->flags )==-1) goto runtime_error; break; case PARALLEL_VAL: /* forward to all location from location set */ intr->proxy.last_to_proxy = 0; /* set the new ip before proxy -> otherwise race cond with rpls */ intr->ip = CPL_TO_CONTINUE; if (cpl_proxy_to_loc_set(intr->msg,&(intr->loc_set),intr->flags) ==-1) goto runtime_error; break; case SEQUENTIAL_VAL: /* forward the request one at the time to all addresses from * loc. set; location set cannot be empty -> was checked before */ /* use the first location from set */ loc = remove_first_location( &(intr->loc_set) ); /* set as the last_to_proxy the last location from set */ intr->proxy.last_to_proxy = intr->loc_set; while (intr->proxy.last_to_proxy&&intr->proxy.last_to_proxy->next) intr->proxy.last_to_proxy = intr->proxy.last_to_proxy->next; /* set the new ip before proxy -> otherwise race cond with rpls */ intr->ip = CPL_TO_CONTINUE; if (cpl_proxy_to_loc_set(intr->msg,&loc,intr->flags)==-1) goto runtime_error; break; } return CPL_TO_CONTINUE;script_error: return CPL_SCRIPT_ERROR;mem_error: LOG(L_ERR,"ERROR:run_proxy: no more free shm memory\n");runtime_error: return CPL_RUNTIME_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -