Ejemplo n.º 1
0
int cf_msg_logger::log(const char* buf, int len,
			 sockaddr_storage* src_ip,
			 sockaddr_storage* dst_ip,
			 cstring method, int reply_code)
{
  string src = addr2str(src_ip);
  string dst = addr2str(dst_ip);

  AmLock _l(fd_mut);

  write_src_dst(src);
  write_src_dst(dst);
  
  string what = c2stlstr(method);
  if(reply_code > 0) {
    what = int2str(reply_code) + " / " + what;
  }

  WRITE_CSTSTR("<call src='");
  WRITE_STLSTR(src);
  WRITE_CSTSTR("' dst='");
  WRITE_STLSTR(dst);
  WRITE_CSTSTR("' desc='");
  WRITE_STLSTR(what);
  WRITE_CSTSTR("'>\n");

  if(write(buf,len) != len) return -1;

  WRITE_CSTSTR("</call>\n");
 
  return 0;
}
Ejemplo n.º 2
0
/** 
 * Computes, set and return the outbound interface
 * based on remote_uri, next_hop_ip, outbound_proxy, route.
 */
int AmBasicSipDialog::getOutboundIf()
{
  if (outbound_interface >= 0)
    return outbound_interface;

  if(AmConfig::SIP_Ifs.size() == 1){
    return (outbound_interface = 0);
  }

  // Destination priority:
  // 1. next_hop
  // 2. outbound_proxy (if 1st req or force_outbound_proxy)
  // 3. first route
  // 4. remote URI
  
  string dest_uri;
  string dest_ip;
  string local_ip;
  multimap<string,unsigned short>::iterator if_it;

  list<sip_destination> ip_list;
  if(!next_hop.empty() && 
     !parse_next_hop(stl2cstr(next_hop),ip_list) &&
     !ip_list.empty()) {

    dest_ip = c2stlstr(ip_list.front().host);
  }
  else if(!outbound_proxy.empty() &&
	  (remote_tag.empty() || force_outbound_proxy)) {
    dest_uri = outbound_proxy;
  }
  else if(!route.empty()){
    // parse first route
    sip_header fr;
    fr.value = stl2cstr(route);
    sip_uri* route_uri = get_first_route_uri(&fr);
    if(!route_uri){
      ERROR("Could not parse route (local_tag='%s';route='%s')",
	    local_tag.c_str(),route.c_str());
      goto error;
    }

    dest_ip = c2stlstr(route_uri->host);
  }
  else {
    dest_uri = remote_uri;
  }

  if(dest_uri.empty() && dest_ip.empty()) {
    ERROR("No destination found (local_tag='%s')",local_tag.c_str());
    goto error;
  }
  
  if(!dest_uri.empty()){
    sip_uri d_uri;
    if(parse_uri(&d_uri,dest_uri.c_str(),dest_uri.length()) < 0){
      ERROR("Could not parse destination URI (local_tag='%s';dest_uri='%s')",
	    local_tag.c_str(),dest_uri.c_str());
      goto error;
    }

    dest_ip = c2stlstr(d_uri.host);
  }

  if(get_local_addr_for_dest(dest_ip,local_ip) < 0){
    ERROR("No local address for dest '%s' (local_tag='%s')",dest_ip.c_str(),local_tag.c_str());
    goto error;
  }

  if_it = AmConfig::LocalSIPIP2If.find(local_ip);
  if(if_it == AmConfig::LocalSIPIP2If.end()){
    ERROR("Could not find a local interface for resolved local IP (local_tag='%s';local_ip='%s')",
	  local_tag.c_str(), local_ip.c_str());
    goto error;
  }

  setOutboundInterface(if_it->second);
  return if_it->second;

 error:
  WARN("Error while computing outbound interface: default interface will be used instead.");
  setOutboundInterface(0);
  return 0;
}
Ejemplo n.º 3
0
//
// Ref. RFC 3261 "12.2.1.1 Generating the Request"
//
int trans_layer::set_next_hop(list<sip_header*>& route_hdrs, 
			      cstring& r_uri, 
			      sockaddr_storage* remote_ip)
{
    string         next_hop;
    unsigned short next_port=0; 

    //assert(msg->type == SIP_REQUEST);

    int err=0;

    if(!route_hdrs.empty()){
	
	sip_header* fr = route_hdrs.front();
	
	sip_nameaddr na;
	const char* c = fr->value.s;
	if(parse_nameaddr(&na, &c, fr->value.len)<0) {
	    
	    DBG("Parsing name-addr failed\n");
	    return -1;
	}
	
	if(parse_uri(&na.uri,na.addr.s,na.addr.len) < 0) {
	    
	    DBG("Parsing route uri failed\n");
	    return -1;
	}

	bool is_lr = false;
	if(!na.uri.params.empty()){
	    
	    list<sip_avp*>::iterator it = na.uri.params.begin();
	    for(;it != na.uri.params.end(); it++){
		
		if( ((*it)->name.len == 2) && 
		    (!memcmp((*it)->name.s,"lr",2)) ) {

		    is_lr = true;
		    break;
		}
	    }

	}

	if (SipCtrlInterfaceFactory::outbound_host.empty()) {
	    next_hop  = c2stlstr(na.uri.host);
	    next_port = na.uri.port;
	} else {
	    next_hop = SipCtrlInterfaceFactory::outbound_host;
	    next_port = SipCtrlInterfaceFactory::outbound_port;
	}	    

	if(!is_lr){
	    
	    // detect beginning of next route

	    enum {
		RR_PARAMS=0,
		RR_QUOTED,
		RR_SEP_SWS,  // space(s) after ','
		RR_NXT_ROUTE
	    };

	    int st = RR_PARAMS;
	    const char* end = fr->value.s + fr->value.len;
	    for(;c<end;c++){
		
		switch(st){
		case RR_PARAMS:
		    switch(*c){
		    case SP:
		    case HTAB:
		    case CR:
		    case LF:
			break;
		    case COMMA:
			st = RR_SEP_SWS;
			break;
		    case DQUOTE:
			st = RR_QUOTED;
			break;
		    }
		    break;
		case RR_QUOTED:
		    switch(*c){
		    case BACKSLASH:
			c++;
			break;
		    case DQUOTE:
			st = RR_PARAMS;
			break;
		    }
		    break;
		case RR_SEP_SWS:
		    switch(*c){
		    case SP:
		    case HTAB:
		    case CR:
		    case LF:
			break;
		    default:
			st = RR_NXT_ROUTE;
			goto nxt_route;
		    }
		    break;
		}
	    }

	nxt_route:
	    
	    switch(st){
	    case RR_QUOTED:
	    case RR_SEP_SWS:
		DBG("Malformed first route header\n");
	    case RR_PARAMS:
		// remove current route header from message
		DBG("delete (fr=0x%p)\n",fr);
		delete fr; // route_hdrs.front();
		route_hdrs.pop_front();
		DBG("route_hdrs.length() = %i\n",(int)route_hdrs.size());
		break;
		
	    case RR_NXT_ROUTE:
		// remove current route from this header
		fr->value.s   = c;
		fr->value.len = end-c;
		break;
	    }

	    
	    // copy r_uri at the end of 
	    // the route set.
	    route_hdrs.push_back(new sip_header(0,"Route",r_uri));

	    r_uri = na.addr;
	}
	
    }
    else {

	if (SipCtrlInterfaceFactory::outbound_host.empty()) {
	    sip_uri parsed_r_uri;
	    err = parse_uri(&parsed_r_uri,r_uri.s,r_uri.len);
	    if(err < 0){
		ERROR("Invalid Request URI\n");
		return -1;
	    }
	    next_hop  = c2stlstr(parsed_r_uri.host);
	    next_port = parsed_r_uri.port;
	} else {
	    next_hop = SipCtrlInterfaceFactory::outbound_host;
	    next_port = SipCtrlInterfaceFactory::outbound_port;
	}
    }

    DBG("next_hop:next_port is <%s:%u>\n", next_hop.c_str(), next_port);
    
    err = resolver::instance()->resolve_name(next_hop.c_str(),
					     remote_ip,IPv4,UDP);
    if(err < 0){
	ERROR("Unresolvable Request URI\n");
	return -1;
    }

    ((sockaddr_in*)remote_ip)->sin_port = htons(next_port);
    
    return 0;
}