Пример #1
0
pcontact_t * getContactP(struct sip_msg* _m, udomain_t* _d, enum pcontact_reg_states reg_state, char service_routes[][MAXROUTESIZE], int num_service_routes) {
	ppublic_t * p;
	contact_body_t *b = 0;
	contact_t *ct;
	pcontact_info_t search_ci;
	str received_host = {0, 0};
	char srcip[50];
	struct via_body *vb;
	unsigned short port, proto;
	str host;
	sip_uri_t contact_uri;
	int mustRetryViaSearch = 0;
	int mustRetryReceivedSearch = 0;

	LM_DBG("number of service routes to look for is %d\n", num_service_routes);
    b = cscf_parse_contacts(_m);

    if (_m->first_line.type == SIP_REPLY && _m->contact && _m->contact->parsed && b->contacts) {
		mustRetryViaSearch = 1;
		mustRetryReceivedSearch = 1;
        LM_DBG("This is a reply - to look for contact we favour the contact header above the via (b2bua)... if no contact we will use last via\n");
        ct = b->contacts;
        host = ct->uri;
        if (parse_uri(ct->uri.s, ct->uri.len, &contact_uri) != 0) {
            LM_WARN("Failed to parse contact [%.*s]\n", ct->uri.len, ct->uri.s);
            return NULL;
        }
        host = contact_uri.host;
        port = contact_uri.port_no ? contact_uri.port_no : 5060;
        proto = contact_uri.proto;
        if (proto == 0) {
            LM_DBG("Contact protocol not specified - using received\n");
            proto = _m->rcv.proto;
        }
    } else {
        if (_m->first_line.type == SIP_REPLY)
            LM_DBG("This is a reply but we are forced to use the via header\n");
        else
            LM_DBG("This is a request - using first via to find contact\n");

        vb = cscf_get_ue_via(_m);
        host = vb->host;
        port = vb->port ? vb->port : 5060;
        proto = vb->proto;
    }

    LM_DBG("searching for contact with host:port:proto contact [%d://%.*s:%d]\n", proto, host.len, host.s, port);

    received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof (srcip));
    received_host.s = srcip;

//    if (_m->id != current_msg_id) {
        current_msg_id = _m->id;
        c = NULL;
	//search_ci.reg_state = PCONTACT_REGISTERED;          //we can do this because this function is always called expecting a REGISTERED contact
	memset(&search_ci, 0, sizeof(struct pcontact_info));
    search_ci.reg_state = reg_state;
	search_ci.received_host.s = received_host.s;
	search_ci.received_host.len = received_host.len;
	search_ci.received_port = _m->rcv.src_port;
	search_ci.received_proto = _m->rcv.proto;
	search_ci.searchflag = SEARCH_RECEIVED;
	search_ci.num_service_routes = 0;
	if (is_registered_fallback2ip == 1) {
		search_ci.searchflag = SEARCH_NORMAL;
	} 
	search_ci.via_host = host;
	search_ci.via_port = port;
	search_ci.via_prot = proto;
	search_ci.aor.s = 0;
	search_ci.aor.len = 0;
	
	int size = num_service_routes==0?1:num_service_routes;
	str s_service_routes[size];
	int i;
	for (i=0;i<num_service_routes;i++) {
		s_service_routes[i].s = service_routes[i];
		s_service_routes[i].len = strlen(service_routes[i]);
		LM_DBG("Setting service routes str for pos %d to %.*s", i, s_service_routes[i].len, s_service_routes[i].s);
	}
	if (num_service_routes > 0) {
		LM_DBG("asked to search for specific service routes...\n");
		search_ci.service_routes = s_service_routes;
		search_ci.num_service_routes = num_service_routes;
		search_ci.extra_search_criteria = SEARCH_SERVICE_ROUTES;
	}

//	b = cscf_parse_contacts(_m);
tryagain:
	if (b && b->contacts) {
		for (ct = b->contacts; ct; ct = ct->next) {
			search_ci.aor = ct->uri;
			if (ul.get_pcontact(_d, &search_ci, &c) == 0) {
				if (checkcontact(_m, c) != 0) {
					c = NULL;
				} else {
					break;
				}
			}
		}
	} else {
		LM_WARN("No contact-header found...\n");
	}

	if ((c == NULL) && (is_registered_fallback2ip == 1)) {
		LM_INFO("Contact not found based on Contact-header, trying IP/Port/Proto\n");
		//			received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
		//			received_host.s = srcip;
		search_ci.searchflag = SEARCH_RECEIVED;
		if (ul.get_pcontact(_d, &search_ci, &c) == 1) {
			LM_DBG("No entry in usrloc for %.*s:%i (Proto %i) found!\n", received_host.len, received_host.s, _m->rcv.src_port, _m->rcv.proto);
		} else {
			if (checkcontact(_m, c) != 0) {
				c = NULL;
			}
		}
	}

	if ((c == NULL) && (is_registered_fallback2ip == 2)) {
		LM_INFO("Contact not found based on IP/Port/Proto, trying Contact-header\n");
		search_ci.searchflag = SEARCH_NORMAL;
		if (ul.get_pcontact(_d, &search_ci, &c) == 1) {
		} else {
			if (checkcontact(_m, c) != 0) {
				c = NULL;
			}
		}
	}

	asserted_identity = NULL;
	registration_contact = NULL;
	if (c) {
                LM_DBG("Trying to set asserted identity field");
		registration_contact = &c->contact_user;
		p = c->head;
		while (p) {
                        LM_DBG("Checking through contact users");
			if (p->is_default == 1) {
                            LM_DBG("Found default contact user so setting asserted identity");
                            asserted_identity = &p->public_identity;
                        }
			p = p->next;
		}
	}
        if (asserted_identity != NULL && asserted_identity->len > 0) {
            LM_DBG("Have set the asserted_identity param to [%.*s]\n", asserted_identity->len, asserted_identity->s);
        } else {
            LM_DBG("Asserted identity not set");
        }
            
    
//    LM_DBG("pcontact flag is [%d]\n", c->flags);
//    if (c && (c->flags & (1<<FLAG_READFROMDB)) != 0) {
//        LM_DBG("we have a contact that was read fresh from the DB....\n");
//    }
	if (!c && mustRetryViaSearch) {
		LM_DBG("This is a reply so we will search using the last via once more...\n");
		vb = cscf_get_ue_via(_m);
		search_ci.via_host = vb->host;
		search_ci.via_port = vb->port ? vb->port : 5060;
		search_ci.via_prot = vb->proto;
		mustRetryViaSearch = 0;
		goto tryagain;
	}
	
	if (!c && mustRetryReceivedSearch) {
		LM_DBG("This is a reply and we still don't have a match - will try src ip/port of message\n");
		search_ci.via_host = received_host;
		search_ci.via_port = _m->rcv.src_port;
		search_ci.via_prot = _m->rcv.proto;
		mustRetryReceivedSearch = 0;
		goto tryagain;
	}

    return c;
}
Пример #2
0
/**
 * get PContact-Structure for message
 * (search only once per Request)
 */
pcontact_t * getContactP(struct sip_msg* _m, udomain_t* _d) {
	ppublic_t * p;
	contact_body_t *b = 0;
	contact_t *ct;
	str received_host = {0, 0};
	char srcip[50];	

	received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
			received_host.s = srcip;
			
	if (_m->id != current_msg_id) {
		current_msg_id = _m->id;
		c = NULL;

		if (is_registered_fallback2ip == 2) {
			LM_DBG("Searching in usrloc for %.*s:%i (Proto %i)\n",
				received_host.len, received_host.s,
				_m->rcv.src_port, _m->rcv.proto);

			if (ul.get_pcontact_by_src(_d, &received_host, _m->rcv.src_port, _m->rcv.proto, &c) == 1) {
				LM_DBG("No entry in usrloc for %.*s:%i (Proto %i) found!\n", received_host.len, received_host.s, _m->rcv.src_port, _m->rcv.proto);
			} else {
				if (checkcontact(_m, c) != 0) {
					c = NULL;
				}
			}
		}

		if (c == NULL) {
			b = cscf_parse_contacts(_m);

			if (b && b->contacts) {
				for (ct = b->contacts; ct; ct = ct->next) {
					if (ul.get_pcontact(_d, &ct->uri, &received_host, _m->rcv.src_port, &c) == 0) {
						if (checkcontact(_m, c) != 0) {
							c = NULL;
						} else {
							break;
						}
					}
				}
			} else {
				LM_WARN("No contact-header found?!?\n");
			}
		}

		if ((c == NULL) && (is_registered_fallback2ip == 1)) {
			LM_INFO("Contact not found based on Contact-header, trying IP/Port/Proto\n");
			received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
			received_host.s = srcip;
			if (ul.get_pcontact_by_src(_d, &received_host, _m->rcv.src_port, _m->rcv.proto, &c) == 1) {
				LM_DBG("No entry in usrloc for %.*s:%i (Proto %i) found!\n", received_host.len, received_host.s, _m->rcv.src_port, _m->rcv.proto);
			} else {
				if (checkcontact(_m, c) != 0) {
					c = NULL;
				}
			}
		}
	}
	asserted_identity = NULL;
	registration_contact = NULL;
	if (c) {
		registration_contact = &c->contact_user;
		p = c->head;
		while (p) {
			if (p->is_default == 1)
				asserted_identity = &p->public_identity;
			p = p->next;
		}
	}

	return c;
}