struct list_res res_walk_parents (const struct res *out, const struct hs *hs, int in_port, array_t* out_arr) { struct res *curr_res = (struct res*) out; struct list_res currq = {0}; // set up initial result to start inversion struct hs int_hs; hs_isect_arr (&int_hs, &out->hs, out_arr); list_append (&currq, res_extend (out, &int_hs, out->port, true)); struct res *cur; while (curr_res) { if (curr_res->rules.cur) { for (int i = curr_res->rules.cur - 1; i >= 0; i--) { struct list_res nextq = {0}; struct res_rule r = curr_res->rules.arr[i]; while ((cur = currq.head)) { list_pop (&currq); struct list_res tmp = rule_inv_apply (r.tf_tf, r.tf_rule, cur, false); list_concat (&nextq, &tmp); res_free (cur); } // for each current result from rule inversion currq = nextq; } // for each rule } else return currq; // set (hs,port) which the inverted (hs,port) results must intersect struct res *parent = curr_res->parent; struct hs *next_hs = hs_create (curr_res->hs.len); int next_port; if (parent) { hs_copy (next_hs, &parent->hs); next_port = parent->port; } else { hs_copy (next_hs, hs); next_port = in_port; } // Intersect the results in `currq` with the target (hs,port) struct list_res nextq = {0}; while ((cur = currq.head)) { list_pop (&currq); struct hs *new_hs = hs_isect_a (&cur->hs, next_hs); if (cur->port == next_port && new_hs) list_append (&nextq, res_extend (cur, new_hs, next_port, false)); else res_free (cur); } currq = nextq; curr_res = parent; } return currq; }
/** * vmw_simple_resource_init - Initialize a simple resource object. * * @dev_priv: Pointer to a struct device private. * @simple: The struct vmw_simple_resource to initialize. * @data: Data passed to the information initialization function. * @res_free: Function pointer to destroy the simple resource. * * Returns: * 0 if succeeded. * Negative error value if error, in which case the resource will have been * freed. */ static int vmw_simple_resource_init(struct vmw_private *dev_priv, struct vmw_simple_resource *simple, void *data, void (*res_free)(struct vmw_resource *res)) { struct vmw_resource *res = &simple->res; int ret; ret = vmw_resource_init(dev_priv, res, false, res_free, &simple->func->res_func); if (ret) { res_free(res); return ret; } ret = simple->func->init(res, data); if (ret) { vmw_resource_unreference(&res); return ret; } simple->res.hw_destroy = simple->func->hw_destroy; return 0; }
void *run() { res_t res; res_init(); res = res_allocate(); sleep(1); res_free(res); return 0; }
result plan_free(Plan plan) { if (plan == NULL) return FAIL; for (int i=0; i < plan->nb_res; i++) if (res_free(plan->res[i]) == FAIL) return FAIL; free(plan->res); free(plan); return OK; }
void res_free (struct res *res) { if (res->refs) { res->next = NULL; return; } hs_destroy (&res->hs); pthread_mutex_destroy (&res->lock); struct res *parent = res->parent; free (res); if (parent) { parent->refs--; res_free (parent); } }
Plan plan_create(Prob prob) { Plan plan = plan_create_empty(prob_res_count(prob)); if (plan == NULL) return NULL; for (int i=0; i < plan->nb_res; i++) { plan->res[i] = res_create(prob_job_count(prob)); if (plan->res[i] == NULL) { for (; i >= 0; i--) res_free(plan->res[i]); free(plan->res); free(plan); return NULL; } } return plan; }
static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { struct unicorn_fh *fh = priv; struct unicorn_dev *dev = fh->dev; int err, res; if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; if (i != fh->type) return -EINVAL; res = get_resource(fh, 0x01 << fh->channel); err = videobuf_streamoff(&fh->vidq); if (err < 0) return err; res_free(dev, fh, res); return 0; }
/*********************************************************************** * I_RpcSendReceive [RPCRT4.@] * * Sends a message to the server and receives the response. * * PARAMS * pMsg [I/O] RPC message information. * * RETURNS * Success: RPC_S_OK. * Failure: Any error code. * * NOTES * The buffer must have been allocated with I_RpcGetBuffer(). * * SEE ALSO * I_RpcGetBuffer(), I_RpcSend(), I_RpcReceive(). */ RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) { RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection * conn = (RpcConnection *)pMsg->ReservedForRuntime; ITgmRpcConnection* theConn = conn->rpc_connection; void* res_buf = 0; ULONG res_len = 0; ipc_client_memory_free_fun_t res_free = NULL; RpcPktHdr *hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation, pMsg->BufferLength, pMsg->ProcNum & ~RPC_FLAGS_VALID_BIT, &bind->ObjectUuid); hdr->common.frag_len += pMsg->BufferLength; char* pkt = (char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,hdr->common.frag_len+1); memcpy(pkt,hdr,hdr->common.frag_len-pMsg->BufferLength); memcpy(pkt+hdr->common.frag_len-pMsg->BufferLength,pMsg->Buffer,pMsg->BufferLength); HRESULT hr = theConn->SendSyncRequestEx(pkt,hdr->common.frag_len,&res_buf,&res_len,&res_free,0); HeapFree(GetProcessHeap(),0,pkt); HeapFree(GetProcessHeap(),0,hdr); HeapFree(GetProcessHeap(),0,pMsg->Buffer); if(SUCCEEDED(hr)) { CRpcUnpacker theUnPacket(res_buf,res_len); pMsg->BufferLength = theUnPacket.get_BufferLength(); pMsg->Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,pMsg->BufferLength); memcpy(pMsg->Buffer,theUnPacket.get_BufferPtr(),pMsg->BufferLength); res_free(res_buf); }else { RPCRT4_DestroyConnection(conn); pMsg->ReservedForRuntime = NULL; } return RPC_S_OK; }
void add_common_resource(resp r) { char outTemp[256]; strp outType; NAMEINFO_NODE *new_nameinfo; if (!r || !r->b || !r->b->buffer) return; /* Refuse to add a resource without data */ ALLOC(new_nameinfo, NAMEINFO_NODE); new_nameinfo->next = NULL; new_nameinfo->data.rcslength = r->b->len; new_nameinfo->data.rcsdata = (LPBYTE)buff_ind(r->b); r->b = NULL; new_nameinfo->data.rcsflags = r->flags; if (!HIWORD(r->name)) { if (LOWORD(r->name) > 0x7fff) FATAL(("Resource identifier %d is too large", (int)(LOWORD(r->name)))); new_nameinfo->data.rcsitemname = (char *)(LOWORD(r->name) | (r->type == RT_STRING ? 0x0000 : 0x8000)); } else new_nameinfo->data.rcsitemname = (char *)(r->name); if (HIWORD(r->type)) new_nameinfo->data.wType = (WORD)(RT_USER_DEF); else new_nameinfo->data.wType = LOWORD(r->type); incr_res_count((char *)r->type, new_nameinfo); if (!HIWORD(r->name)) sprintf(outTemp, "%d", (int)r->name); else sprintf(outTemp, "%s", r->name); outType = resource_type_name(r->type); VPRINT(("Added resource: %s %s", outType, outTemp)); str_free(outType); res_free(r); }
// Perform a DNS query and parse the results. Follows CNAME records. void SipSrvLookup::res_query_and_parse(const char* in_name, int type, res_response* in_response, const char*& out_name, res_response*& out_response ) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipSrvLookup::res_query_and_parse in_name = '%s', " "type = %d (%s)", in_name,type, type == T_CNAME ? "CNAME" : type == T_SRV ? "SRV" : type == T_A ? "A" : type == T_NAPTR ? "NAPTR" : "unknown"); // The number of CNAMEs we have followed. int cname_count = 0; // The response currently being examined. res_response* response = in_response; // The name currently being examined. const char* name = in_name; // TRUE if 'response' was a lookup for 'name' and 'type'. UtlBoolean response_for_this_name = FALSE; // Buffer into which to read DNS replies. char answer[DNS_RESPONSE_SIZE]; union u_rdata* p; // Loop until we find a reason to exit. Each turn around the loop does // another DNS lookup. while (1) { // While response != NULL and there is a CNAME record for name // in response. while (response != NULL && (p = look_for(response, name, T_CNAME)) != NULL) { cname_count++; if (cname_count > SipSrvLookup::getOption(SipSrvLookup::OptionCodeCNAMELimit)) { break; } // If necessary, free the current 'name'. if (name != in_name) { free((void*) name); } // Copy the canonical name from the CNAME record into 'name', so // we can still use it after freeing 'response'. name = strdup(p->string); // Remember that we are now looking for a name that was not the one // that we searched for to produce this response. Hence, if we don't // find any RRs for it, that is not authoritative and we have to do // another DNS query. response_for_this_name = FALSE; // Go back and check whether the result name of the CNAME is listed // in this response. } // This response does not contain a CNAME for 'name'. So it is either // a final response that gives us the RRs we are looking for, or // we need to do a lookup on 'name'. // Check whether the response was for this name, or contains records // of the type we are looking for. If either, then any records we // are looking for are in this response, so we can return. if (response_for_this_name || (response != NULL && look_for(response, name, type) != NULL)) { break; } // We must do another lookup. // Start by freeing 'response' if we need to. if (response != in_response) { res_free(response); } response = NULL; // Now, 'response' will be from a query for 'name'. response_for_this_name = TRUE; // Debugging print. if (SipSrvLookup::getOption(SipSrvLookup::OptionCodePrintAnswers)) { printf("res_nquery(\"%s\", class = %d, type = %d)\n", name, C_IN, type); } // Initialize the res state struct and set the timeout to // 3 secs and retries to 2 struct __res_state res; res_ninit(&res); res.retrans = mTimeout; res.retry = mRetries; if (!mNameserverIP.isNull()) { res.nscount = 1; inet_aton(mNameserverIP.data(), &res.nsaddr_list[0].sin_addr); if (mNameserverPort > 1) { res.nsaddr_list[0].sin_port = htons(mNameserverPort); } } // Use res_nquery, not res_search or res_query, so defaulting rules are not // applied to the domain, and so that the query is thread-safe. int r = res_nquery(&res, name, C_IN, type, (unsigned char*) answer, sizeof (answer)); // Done with res state struct, so cleanup. // Must close once and only once per res_ninit, after res_nquery. res_nclose(&res); if (r == -1) { // res_query failed, return. OsSysLog::add(FAC_SIP, PRI_WARNING, "DNS query for name '%s', " "type = %d (%s): returned error", name, type, type == T_CNAME ? "CNAME" : type == T_SRV ? "SRV" : type == T_A ? "A" : type == T_NAPTR ? "NAPTR" : "unknown"); break; } response = res_parse((char*) &answer); if (response == NULL) { // res_parse failed, return. OsSysLog::add(FAC_SIP, PRI_WARNING, "DNS query for name '%s', " "type = %d (%s): response could not be parsed", name, type, type == T_CNAME ? "CNAME" : type == T_SRV ? "SRV" : type == T_A ? "A" : type == T_NAPTR ? "NAPTR" : "unknown"); break; } // If requested for testing purposes, sort the query and print it. // Sort first, so we see how sorting came out. if (SipSrvLookup::getOption(SipSrvLookup::OptionCodeSortAnswers)) { sort_answers(response); } if (SipSrvLookup::getOption(SipSrvLookup::OptionCodePrintAnswers)) { res_print(response); } // Now that we have a fresh DNS query to analyze, go back and check it // for a CNAME for 'name' and then for records of the requested type. } // Final processing: Copy the working name and response to the output // variables. out_name = name; out_response = response; OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipSrvLookup::res_query_and_parse out_name = '%s', out_response = %p", out_name, out_response); }
/* * Look up A records for a domain name, and insert them into the list * of servers. */ void lookup_A(server_t*& list, int& list_length_allocated, int& list_length_used, const char* domain, ///< domain name OsSocket::IpProtocolSocketType proto_code, ///< protocol code for result list res_response* in_response, ///< current DNS response, or NULL int port, ///< port unsigned int priority, ///< priority unsigned int weight ///< weight ) { // To hold the return of res_query_and_parse. res_response* response; const char* canonical_name; // Make the query and parse the response. SipSrvLookup::res_query_and_parse(domain, T_A, in_response, canonical_name, response); OsLock lock(SipSrvLookupThread::slookupThreadMutex); // Search the list of RRs. // For each answer that is an A record for this domain name. if (response != NULL) { unsigned int i; // Search the answer list. for (i = 0; i < response->header.ancount; i++) { if (response->answer[i]->rclass == C_IN && response->answer[i]->type == T_A && // Note we look for the canonical name now. strcasecmp(canonical_name, response->answer[i]->name) == 0) { // An A record has been found. // Assemble the needed information and add it to the server list. struct sockaddr_in sin; memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_addr = response->answer[i]->rdata.address; sin.sin_family = AF_INET; sin.sin_port = htons(port); server_insert_addr(list, list_length_allocated, list_length_used, (const char*) domain, proto_code, sin, priority, weight); } } // Search the additional list. for (i = 0; i < response->header.arcount; i++) { if (response->additional[i]->rclass == C_IN && response->additional[i]->type == T_A && // Note we look for the canonical name now. strcasecmp(canonical_name, response->additional[i]->name) == 0) { // An A record has been found. // Assemble the needed information and add it to the server list. struct sockaddr_in sin; memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_addr = response->additional[i]->rdata.address; sin.sin_family = AF_INET; sin.sin_port = htons(port); server_insert_addr(list, list_length_allocated, list_length_used, (const char*) domain, proto_code, sin, priority, weight); } } } // Free the result of res_parse if necessary. if (response != NULL && response != in_response) { res_free(response); } if (canonical_name != NULL && canonical_name != domain) { free((void*) canonical_name); } }
/* * Look up SRV records for a domain name, and from them find server * addresses to insert into the list of servers. */ void lookup_SRV(server_t*& list, int& list_length_allocated, int& list_length_used, const char* domain, ///< domain name const char* service, ///< "sip" or "sips" const char* proto_string, ///< protocol string for DNS lookup OsSocket::IpProtocolSocketType proto_code ///< protocol code for result list ) { // To hold the return of res_query_and_parse. res_response* response; const char* canonical_name; // Construct buffer to hold the key string for the lookup: // _service._protocol.domain // 5 bytes suffices for the added components and the ending NUL. char* lookup_name = (char*) malloc(strlen(service) + strlen(proto_string) + strlen(domain) + 5); // Construct the domain name to search on. sprintf(lookup_name, "_%s._%s.%s", service, proto_string, domain); // Make the query and parse the response. SipSrvLookup::res_query_and_parse(lookup_name, T_SRV, NULL, canonical_name, response); if (response != NULL) { unsigned int i; // For each answer that is an SRV record for this domain name. // Search the answer list of RRs. for (i = 0; i < response->header.ancount; i++) { if (response->answer[i]->rclass == C_IN && response->answer[i]->type == T_SRV && // Note we look for the canonical name now. strcasecmp(canonical_name, response->answer[i]->name) == 0) { // Call lookup_A to get the A records for the target host // name. Give it the pointer to our current response, // because it might have the A records. If not, lookup_A // will do a DNS lookup to get them. lookup_A(list, list_length_allocated, list_length_used, response->answer[i]->rdata.srv.target, proto_code, response, response->answer[i]->rdata.srv.port, response->answer[i]->rdata.srv.priority, response->answer[i]->rdata.srv.weight); } } // Search the additional list of RRs. for (i = 0; i < response->header.arcount; i++) { if (response->additional[i]->rclass == C_IN && response->additional[i]->type == T_SRV && // Note we look for the canonical name now. strcasecmp(canonical_name, response->additional[i]->name) == 0) { // Call lookup_A to get the A records for the target host // name. Give it the pointer to our current response, // because it might have the A records. If not, lookup_A // will do a DNS lookup to get them. lookup_A(list, list_length_allocated, list_length_used, response->additional[i]->rdata.srv.target, proto_code, response, response->additional[i]->rdata.srv.port, response->additional[i]->rdata.srv.priority, response->additional[i]->rdata.srv.weight); } } } // Free the result of res_parse. if (response != NULL) { res_free(response); } if (canonical_name != NULL && canonical_name != lookup_name) { free((void*) canonical_name); } free((void*) lookup_name); }
static void * reach_thread (void *vdata) { struct tdata *data = vdata; int sw = data->sw; struct list_res *res = &data->res; const uint32_t *out = g_out; int nout = g_nout; int ntfs = data_file->ntfs - 1; //int count = 0, loops = 0; while (true) { struct list_res queue = {0}; pthread_mutex_lock (&wait_lock); //fprintf (stderr, "%d %d\n", sw, queues[sw].n); while (!queues[sw].head) { waiters |= 1 << sw; if (waiters + 1 == 1 << ntfs) { for (int i = 0; i < ntfs; i++) { if (i == sw) continue; pthread_cond_broadcast (&conds[i]); } pthread_mutex_unlock (&wait_lock); return NULL; } pthread_cond_wait (&conds[sw], &wait_lock); if (waiters + 1 == 1 << ntfs) { pthread_mutex_unlock (&wait_lock); return NULL; } assert (waiters | (1 << sw)); } queue = queues[sw]; memset (&queues[sw], 0, sizeof queues[sw]); pthread_mutex_unlock (&wait_lock); struct res *cur; while ((cur = queue.head)) { list_pop (&queue); bool new_res = false; struct list_res nextqs[ntfs]; memset (nextqs, 0, sizeof nextqs); struct list_res ntf_res = ntf_apply (cur, sw); struct res *ntf_cur = ntf_res.head; while (ntf_cur) { struct res *ntf_next = ntf_cur->next; if (!out || int_find (ntf_cur->port, out, nout)) { list_append (res, ntf_cur); ref_add (ntf_cur, cur); if (out) { ntf_cur = ntf_next; continue; } } struct list_res ttf_res = tf_apply (tf_get (0), ntf_cur, true); struct res *ttf_cur = ttf_res.head; while (ttf_cur) { struct res *ttf_next = ttf_cur->next; if (is_loop (ttf_cur->port, cur)) { res_free (ttf_cur); ttf_cur = ttf_next; //loops++; continue; } ref_add (ttf_cur, cur); if (out && int_find (ttf_cur->port, out, nout)) list_append (res, ttf_cur); else { int new_sw = ntf_get_sw (ttf_cur->port); list_append (&nextqs[new_sw], ttf_cur); //count++; new_res = true; } ttf_cur = ttf_next; } if (out) res_free (ntf_cur); ntf_cur = ntf_next; } res_free_mt (cur, true); if (!new_res) continue; pthread_mutex_lock (&wait_lock); unsigned int wake = 0; for (int i = 0; i < ntfs; i++) { if (!nextqs[i].head) continue; list_concat (&queues[i], &nextqs[i]); pthread_cond_broadcast (&conds[i]); wake |= 1 << i; } waiters &= ~wake; pthread_mutex_unlock (&wait_lock); } } }
RedirectPlugin::LookUpStatus SipRedirectorISN::lookUp( const SipMessage& message, const UtlString& requestString, const Url& requestUri, const UtlString& method, ContactList& contactList, RequestSeqNo requestSeqNo, int redirectorNo, SipRedirectorPrivateStorage*& privateStorage, ErrorDescriptor& errorDescriptor) { bool status = false; // Get the user part. UtlString userId; requestUri.getUserId(userId); // Test if the user part is in the right format -- prefix followed by digits*digits const char* user = userId.data(); int prefix_length = mPrefix.length(); // Compare the prefix. int i; // Length of the extension part. if (strncmp(user, mPrefix.data(), prefix_length) == 0) { // Effectively delete the prefix from the user part. user += prefix_length; // Check the syntax of the remainder of the user. i = strspn(user, "0123456789"); int j = 0; if (i > 0) { if (user[i] == '*') { j = strspn(user + i + 1, "0123456789"); if (user[i + 1 + j] == '\0') { status = true; } } } } if (status) { // Format of user part is correct. Look for NAPTR records. // Create the domain to look up. char domain[2 * strlen(user) + mBaseDomain.length()]; { char* p = &domain[0]; // Copy the extension, reversing it and following each digit with a period. for (int k = i; --k >= 0; ) { *p++ = user[k]; *p++ = '.'; } // Append the ITAD and a period. strcpy(p, user + i + 1); strcat(p, "."); // Append the ITAD root domain. strcat(p, mBaseDomain.data()); } OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::lookUp user '%s' has ISN format, domain is '%s'", mLogName.data(), user, domain); // To hold the return of res_query_and_parse. res_response* dns_response; const char* canonical_name; // Make the query and parse the response. SipSrvLookup::res_query_and_parse(domain, T_NAPTR, NULL, canonical_name, dns_response); if (dns_response != NULL) { // Search the list of RRs for the 'best' answer. // Initialize to values at least 2**16. int lowest_order_seen = 1 << 16, lowest_preference_seen = 1 << 16; int best_response = -1; // No response found.. // Search the answer list. for (unsigned int i = 0; i < dns_response->header.ancount; i++) { if (dns_response->answer[i]->rclass == C_IN && dns_response->answer[i]->type == T_NAPTR && // Note we look for the canonical name now. strcasecmp(canonical_name, dns_response->answer[i]->name) == 0) { // A NAPTR record has been found. OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::LookUp " "NAPTR record found '%s' %d %d %d %d '%s' '%s' '%s' '%s'", mLogName.data(), dns_response->answer[i]->name, dns_response->answer[i]->rclass, dns_response->answer[i]->type, dns_response->answer[i]->rdata.naptr.order, dns_response->answer[i]->rdata.naptr.preference, dns_response->answer[i]->rdata.naptr.flags, dns_response->answer[i]->rdata.naptr.services, dns_response->answer[i]->rdata.naptr.regexp, dns_response->answer[i]->rdata.naptr.replacement); // Accept the record if flags are 'u' and services are 'E2U+sip'. // Note that the value 'E2U+sip' is defined by RFC 3764 // (SIP enumservice) not RFC 2915 (the original NAPTR RFC). if (strcasecmp(dns_response->answer[i]->rdata.naptr.flags, "u") == 0 && strcasecmp(dns_response->answer[i]->rdata.naptr.services, "E2U+sip") == 0) { // Check that it has the lowest order and preference values seen so far. if (dns_response->answer[i]->rdata.naptr.order < lowest_order_seen || (dns_response->answer[i]->rdata.naptr.order == lowest_order_seen && dns_response->answer[i]->rdata.naptr.preference < lowest_preference_seen)) { best_response = i; lowest_order_seen = dns_response->answer[i]->rdata.naptr.order; lowest_preference_seen = dns_response->answer[i]->rdata.naptr.preference; } } } } // At this point, best_response (if any) is the response we chose. if (best_response != -1) { char* p = dns_response->answer[best_response]->rdata.naptr.regexp; OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::LookUp Using NAPTR rewrite '%s' for '%s'", mLogName.data(), p, domain); // Enough space for the 'match' part of the regexp field. char match[strlen(p) + 1]; // Pointer to the 'replace' part of the regexp field. char delim; const char* replace; int i_flag; if (res_naptr_split_regexp(p, &delim, match, &replace, &i_flag)) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::LookUp match = '%s', replace = '%s', i_flag = %d", mLogName.data(), match, replace, i_flag); // Split operation was successful. Try to match. regex_t reg; int ret = regcomp(®, match, REG_EXTENDED | (i_flag ? REG_ICASE : 0)); if (ret == 0) { // NAPTR matches can have only 9 substitutions. regmatch_t pmatch[9]; // regexec returns 0 for success. // Though RFC 3761 and the ISN Cookbook don't say, it appears // that the regexp is matched against the user-part of the SIP URI. if (regexec(®, user, 9, pmatch, 0) == 0) { // Match was successful. Construct the replacement string. // Current usage is that the replacement string is the resulting URI, // not the replacement into the original application-string. char* result = res_naptr_replace(replace, delim, pmatch, user, 0); OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::LookUp result = '%s'", mLogName.data(), result); // Note that the replacement string is not // substituted back into the original string, but used // alone as the destination URI. // Parse result string into URI. Url contact(result, TRUE); // Almost all strings are parsable as SIP URIs with a sufficient // number of components missing. But we can check that a scheme // was identified, and that a host name was found. // (A string with sufficiently few punctuation characters appears to // be a sip: URI with the scheme missing and only a host name, but // the legal character set for host names is fairly narrow.) UtlString h; contact.getHostAddress(h); if (contact.getScheme() != Url::UnknownUrlScheme && !h.isNull()) { contactList.add(contact, *this); } else { OsSysLog::add(FAC_SIP, PRI_ERR, "%s::LookUp Bad result string '%s' - " "could not identify URI scheme and/or host name is null - " "for ISN translation of '%s'", mLogName.data(), result, requestString.data()); } // Free the result string. free(result); } else { OsSysLog::add(FAC_SIP, PRI_WARNING, "%s::LookUp NAPTR regexp '%s' does not match " "for ISN translation of '%s' - no contact generated", mLogName.data(), match, requestString.data()); } // Free the parsed regexp structure. regfree(®); } else { OsSysLog::add(FAC_SIP, PRI_WARNING, "%s::LookUp NAPTR regexp '%s' is syntactially invalid " "for ISN translation of '%s'", mLogName.data(), match, requestString.data()); } } else { OsSysLog::add(FAC_SIP, PRI_ERR, "%s::LookUp cannot parse NAPTR regexp field '%s' " "for ISN translation of '%s'", mLogName.data(), p, requestString.data()); } } else { OsSysLog::add(FAC_SIP, PRI_WARNING, "%s::LookUp No usable NAPTR found for '%s'" "for ISN translation of '%s'", mLogName.data(), domain, requestString.data()); } } else { OsSysLog::add(FAC_SIP, PRI_WARNING, "%s::LookUp no NAPTR record found for domain '%s' " "for ISN translation of '%s'", mLogName.data(), domain, requestString.data()); } // Free the result of res_parse if necessary. if (dns_response != NULL) { res_free(dns_response); } if (canonical_name != NULL && canonical_name != domain) { free((void*) canonical_name); } } return RedirectPlugin::SUCCESS; }