⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srv_resolv.c

📁 jabber server jabber server jabber server jabber server
💻 C
📖 第 1 页 / 共 2 页
字号:
     register HEADER* rheader;		   /* Reply header*/     unsigned char*   rrptr;		   /* Current Resource record ptr */     int              exprc;		   /* dn_expand return code */     int              rrtype;     long             rrpayloadsz;     srv_list       svrlist  = NULL;     srv_list       tempnode = NULL;     srv_list       iternode = NULL;     xht	      arr_table;	   /* Hash of A records (name, ip) */     spool            result;     int	      result_is_empty = 1;     char*            ipname;     char*            ipaddr;#ifdef WITH_IPV6     int	      error_code;     struct addrinfo  hints;     struct addrinfo* addr_res;#else     struct hostent*  hp;#endif    /* If no service is specified, use a standard gethostbyname call */    if (service == NULL) {	result = spool_new(p);	if (srv_lookup_aaaa_a(result, domain) == 0) {	    return spool_print(result);	} else {	    return NULL;	}    }    log_debug2(ZONE, LOGT_IO, "srv: SRV resolution of %s.%s", service, domain);    /* Setup A record hash table */    arr_table = xhash_new(11);    /* Initialize lookup system if needed (check global _res structure) */    if (((_res.options & RES_INIT) == 0) && (res_init() == -1)) {	log_debug2(ZONE, LOGT_IO, "srv: initialization failed on res_init.");	return NULL;    }    /* Run a SRV query against the specified domain */    replylen = res_querydomain(service, domain,	    C_IN,			/* Class */	    T_SRV,			/* Type */	    (unsigned char*)&reply,	/* Answer buffer */	    sizeof(reply));		/* Answer buffer sz */    /* Setup a pointer to the reply header */    rheader = (HEADER*)reply;    /* Process SRV response if all conditions are met per RFC 2052:     * 1.) reply has some data available     * 2.) no error occurred     * 3.) there are 1 or more answers available */    if ( (replylen > 0) && (ntohs(rheader->rcode) == NOERROR) && (ntohs(rheader->ancount) > 0) ) {	/* Parse out the Question section, and get to the following 	 * RRs (see RFC 1035-4.1.2) */	exprc = dn_expand(reply,	/* Msg ptr */		reply + replylen,	/* End of msg ptr */		reply + sizeof(HEADER),	/* Offset into msg */		host, sizeof(host));	/* Dest buffer for expansion */	if (exprc < 0) {	    log_debug2(ZONE, LOGT_IO, "srv: DN expansion failed for Question section.");	    return NULL;	}	/* Determine offset of the first RR */	rrptr = reply + sizeof(HEADER) + exprc + 4;	/* Walk the RRs, building a list of targets */	while (rrptr < (reply + replylen)) {	    /* Expand the domain name */	    exprc = dn_expand(reply, reply + replylen, rrptr, host, sizeof(host));	    if (exprc < 0) {		log_debug2(ZONE, LOGT_IO, "srv: Whoa nelly! DN expansion failed for RR.");		return NULL;	    }	    /* Jump to RR info */	    rrptr += exprc;	    rrtype      = (rrptr[0] << 8 | rrptr[1]);  /* Extract RR type */	    rrpayloadsz = (rrptr[8] << 8 | rrptr[9]);  /* Extract RR payload size */	    rrptr += 10;	    /* Process the RR */	    switch(rrtype) {#ifdef WITH_IPV6		/* AAAA records should be hashed for the duration of this lookup */		case T_AAAA:		    /* Allocate a new string to hold the IP address */		    ipaddr = srv_inet_ntop(p, rrptr, AF_INET6);		    /* Copy the domain name */		    ipname = pstrdup(p, host);		    /* Insert name/ip into hash table for future reference */		    srv_xhash_join(p, arr_table, ipname, ipaddr);		   break;#endif		/* A records should be hashed for the duration of this lookup */		case T_A: 		    /* Allocate a new string to hold the IP address */		    ipaddr = srv_inet_ntoa(p, rrptr);		    /* Copy the domain name */		    ipname = pstrdup(p, host);		    /* Insert name/ip into hash table for future reference */		    srv_xhash_join(p, arr_table, ipname, ipaddr);		    		    break;		/* SRV records should be stored in a sorted list */		case T_SRV:		    /* Expand the target name */		    exprc = dn_expand(reply, reply + replylen, rrptr + 6, host, sizeof(host));		    if (exprc < 0) {			log_debug2(ZONE, LOGT_IO, "srv: DN expansion failed for SRV.");			return NULL;		    }		    /* Create a new node */		    tempnode = pmalloco(p, sizeof(_srv_list));		    tempnode->priority = (rrptr[0] << 8 | rrptr[1]);		    tempnode->port     = srv_port2str(p, (rrptr[4] << 8 | rrptr[5]));		    tempnode->host     = pstrdup(p, host);		    log_debug2(ZONE, LOGT_IO, "found SRV record pointing to %s", tempnode->host);		    /* Insert the node in the list */		    		    if (svrlist == NULL) {			/* first result */			svrlist = tempnode;		    } else {			srv_list iternode_before = NULL;			/* insert result in ordered list */			iternode = svrlist;	/* HEAD of list (smallest priority value) */						/* find element that stays in front of the new one */			/* XXX for elements with the same priority we should use the weight to order			 * the elements in the list. We are now just ignoring the weight resulting			 * in an equal distribution across results of the same priority */			while (iternode != NULL && iternode->priority < tempnode->priority) {			    iternode_before = iternode; /* keep pointer to the element before */			    iternode = iternode->next;	/* switch to next element */			}			/* iternode now either points to NULL (insert as last element)			 * or it points to the element after the new one			 *			 * iternode_before now either point to NULL (insert as first element)			 * or it points to the element in front of the new one */			/* insert the new element in the list */			/* update pointers in the new element */			tempnode->next = iternode;			tempnode->last = iternode_before;			/* update pointer in the previous element */			if (iternode_before != NULL) {			    iternode_before->next = tempnode;			} else {			    /* we are the first element */			    svrlist = tempnode;			}			/* update pointer in the following element */			if (iternode != NULL) {			    iternode->last = tempnode;			}		    }	    } /* end..switch */	    /* Increment to next RR */	    rrptr += rrpayloadsz;	}	/* Now, walk the nicely sorted list and resolve the target's A records, sticking the resolved name in	 * a spooler -- hopefully these have been pre-cached, and arrived along with the SRV reply */	result = spool_new(p);	iternode = svrlist;	while (iternode != NULL) {	    log_debug2(ZONE, LOGT_IO, "processing SRV record pointing to %s", iternode->host);	    /* Check the AAAA/A record hash table first.. */	    ipaddr = (char*)xhash_get(arr_table, iternode->host);	    /* it hasn't been in the additional section, we have to lookup the IP address */	    if (ipaddr == NULL) {		spool temp_result = spool_new(p);		log_debug2(ZONE, LOGT_IO, "'%s' not in additional section of DNS reply, looking it up using AAAA/A query", iternode->host);		srv_lookup_aaaa_a(temp_result, iternode->host);		ipaddr = spool_print(temp_result);	    }	   	    if (j_strlen(ipaddr) > 0) {		/* copy the ipaddr as we will modify it */		char *ptrptr, *token, *ipaddr_copy = strdup(ipaddr);		/* if there has been a result already, we have to separate by a "," */		if (!result_is_empty) {		    spool_add(result, ",");		} else {		    result_is_empty = 0;		}		/* add the port number for each address */		token = strtok_r(ipaddr_copy, ",", &ptrptr);		while (token != NULL) {		    if (strchr(token, ':')) {			/* IPv6 format */			spooler(result, "[", token, "]:", iternode->port, result);		    } else {			/* IPv4 format */			spooler(result, token, ":", iternode->port, result);		    }		    /* get next token */		    token = strtok_r(NULL, ",", &ptrptr);		    if (token) {			spool_add(result, ","); /* separate results by ',' */		    }		}		/* free our tokenized copy */		free(ipaddr_copy);	    }	    iternode = iternode->next;	}	/* Finally, turn the fully resolved list into a string <ip>:<host>,... */	return spool_print(result);    }    /* Otherwise, return NULL -- it's for the caller to finish up by using     * standard A records */    return NULL;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -