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

📄 dnsrv.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -------------------------------------------------------------------------- * * License * * The contents of this file are subject to the Jabber Open Source License * Version 1.0 (the "JOSL").  You may not copy or use this file, in either * source code or executable form, except in compliance with the JOSL. You * may obtain a copy of the JOSL at http://www.jabber.org/ or at * http://www.opensource.org/.   * * Software distributed under the JOSL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL * for the specific language governing rights and limitations under the * JOSL. * * Copyrights *  * Portions created by or assigned to Jabber.com, Inc. are  * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact * information for Jabber.com, Inc. is available at http://www.jabber.com/. * * Portions Copyright (c) 1998-1999 Jeremie Miller. *  * Acknowledgements *  * Special thanks to the Jabber Open Source Contributors for their * suggestions and support of Jabber. *  * Alternatively, the contents of this file may be used under the terms of the * GNU General Public License Version 2 or later (the "GPL"), in which case * the provisions of the GPL are applicable instead of those above.  If you * wish to allow use of your version of this file only under the terms of the * GPL and not to allow others to use your version of this file under the JOSL, * indicate your decision by deleting the provisions above and replace them * with the notice and other provisions required by the GPL.  If you do not * delete the provisions above, a recipient may use your version of this file * under either the JOSL or the GPL.  *  *  * --------------------------------------------------------------------------*/#include "jabberd.h"#include "srv_resolv.h"#include <sys/wait.h>#ifdef __CYGWIN__#include <process.h>#endif/* Config format:   <dnsrv xmlns='jabber:config:dnsrv'>      <resend service="_jabber._tcp">foo.org</resend>      ...   </dnsrv>   Notes:   * You must specify the services in the order you want them tried*//* ------------------------------------------------- *//* Struct to store list of services and resend hosts */typedef struct __dns_resend_list{     char* service;     char* host;     struct __dns_resend_list* next;} *dns_resend_list, _dns_resend_list;/* --------------------------------------- *//* Struct to keep track of a DNS coprocess */typedef struct{     int             in;                 /* Inbound data handle */     int             out;                /* Outbound data handle */     int             pid;                /* Coprocess PID */     HASHTABLE       packet_table; /* Hash of dns_packet_lists */     int             packet_timeout; /* how long to keep packets in the queue */     HASHTABLE       cache_table; /* Hash of resolved IPs */     int             cache_timeout; /* how long to keep resolutions in the cache */     pool            mempool;     dns_resend_list svclist;} *dns_io, _dns_io;typedef int (*RESOLVEFUNC)(dns_io di);/* ----------------------------------------------------------- *//* Struct to store list of dpackets which need to be delivered */typedef struct __dns_packet_list{     dpacket           packet;     int               stamp;     struct __dns_packet_list* next;} *dns_packet_list, _dns_packet_list;// ---------------------------------------------------------------------------// This code is not used in cygwin#ifndef __CYGWIN__/* ----------------------- *//* Coprocess functionality */void dnsrv_child_process_xstream_io(int type, xmlnode x, void* args){     dns_io di = (dns_io)args;     char*  hostname;     char*  str = NULL;     dns_resend_list iternode = NULL;     if (type == XSTREAM_NODE)     {          /* Get the hostname out... */          hostname = xmlnode_get_data(x);          log_debug(ZONE, "dnsrv: Recv'd lookup request for %s", hostname);          if (hostname != NULL)          {               /* For each entry in the svclist, try and resolve using                  the specified service and resend it to the specified host */               iternode = di->svclist;               while (iternode != NULL)               {                    str = srv_lookup(x->p, iternode->service, hostname);                    if (str != NULL)                    {                         log_debug(ZONE, "Resolved %s(%s): %s\tresend to:%s", hostname, iternode->service, str, iternode->host);                         xmlnode_put_attrib(x, "ip", str);                         xmlnode_put_attrib(x, "to", iternode->host);                         break;                    }                    iternode = iternode->next;               }               str = xmlnode2str(x);               write(di->out, str, strlen(str));          }     }     xmlnode_free(x);}int dnsrv_child_main(dns_io di){     pool    p   = pool_new();     xstream xs  = xstream_new(p, dnsrv_child_process_xstream_io, di);     int     len;     char    readbuf[1024];     sigset_t sigs;     sigemptyset(&sigs);     sigaddset(&sigs, SIGHUP);     sigprocmask(SIG_BLOCK, &sigs, NULL);     log_debug(ZONE,"DNSRV CHILD: starting");     /* Transmit stream header */     write(di->out, "<stream>", 8);     /* Loop forever, processing requests and feeding them to the xstream*/          while (1)     {       len = read(di->in, &readbuf, 1024);       if (len <= 0)       {           log_debug(ZONE,"dnsrv: Read error on coprocess(%d): %d %s",getppid(),errno,strerror(errno));           break;       }       log_debug(ZONE, "DNSRV CHILD: Read from buffer: %.*s",len,readbuf);       if (xstream_eat(xs, readbuf, len) > XSTREAM_NODE)       {           log_debug(ZONE, "DNSRV CHILD: xstream died");           break;       }     }     /* child is out of loop... normal exit so parent will start us again */     log_debug(ZONE, "DNSRV CHILD: out of loop.. exiting normal");     pool_free(p);     exit(0);     return 0;}/* Core functionality */int dnsrv_fork_and_capture(RESOLVEFUNC f, dns_io di){     int left_fds[2], right_fds[2];     int pid;     /* Create left and right pipes */     if (pipe(left_fds) < 0 || pipe(right_fds) < 0)          return -1;     pid = pth_fork();     if (pid < 0)          return -1;     else if (pid > 0)          /* Parent */     {          /* Close unneeded file handles */          close(left_fds[STDIN_FILENO]);          close(right_fds[STDOUT_FILENO]);          /* Return the in and out file descriptors */          di->in = right_fds[STDIN_FILENO];          di->out = left_fds[STDOUT_FILENO];          return pid;     }     else                       /* Child */     {          /* Close unneeded file handles */          pth_kill();          close(left_fds[STDOUT_FILENO]);          close(right_fds[STDIN_FILENO]);          /* Start the specified function, passing the in/out descriptors */          di->in = left_fds[STDIN_FILENO]; di->out = right_fds[STDOUT_FILENO];          return (*f)(di);     }}#endif// ---------------------------------------------------------------------------// Replacement functions for cygwin#ifdef __CYGWIN__/** * Dummy dnsrv_child_main */int dnsrv_child_main(dns_io di) {  return 0;}/** * Spawn a separate process for ADNS  */int dnsrv_fork_and_capture(RESOLVEFUNC f, dns_io di){  int pid;  int childToParent[2];  int parentToChild[2];  char childWriteHandle[10];    char childReadHandle[10];  char debugging[10];  int READ=0;  int WRITE=1;    // create pipes for communication with child  pipe(childToParent);  pipe(parentToChild);  // convert the handles as they should be seen by the child to   // strings so we can pass them as arguments to it  sprintf(childWriteHandle, "%i", childToParent[WRITE]);  sprintf(childReadHandle, "%i", parentToChild[READ]);  sprintf(debugging, "%i", get_debug_flag());    // try and spawn the child process  pid = spawnlp(_P_NOWAIT, "jabadns", "jabadns",                 childReadHandle, childWriteHandle, debugging, NULL);  if (pid < 0) {    return -1;  }    // setup di structure  di->pid = pid;  di->in = childToParent[READ];  di->out = parentToChild[WRITE];    // OK!  return pid;}#endifvoid dnsrv_resend(xmlnode pkt, char *ip, char *to){    if(ip != NULL)    {         pkt = xmlnode_wrap(pkt,"route");         xmlnode_put_attrib(pkt, "to", to);         xmlnode_put_attrib(pkt, "ip", ip);    }else{         jutil_error(pkt, (terror){502, "Unable to resolve hostname."});         xmlnode_put_attrib(pkt, "iperror", "");    }    deliver(dpacket_new(pkt),NULL);}/* Hostname lookup requested */void dnsrv_lookup(dns_io d, dpacket p){    dns_packet_list l, lnew;    xmlnode req;    char *reqs;    /* make sure we have a child! */    if(d->out <= 0)    {        deliver_fail(p, "DNS Resolver Error");        return;    }    /* Attempt to lookup this hostname in the packet table */    l = (dns_packet_list)ghash_get(d->packet_table, p->host);    /* IF: hashtable has the hostname, a lookup is already pending,       so push the packet on the top of the list (most recent at the top) */    if (l != NULL)    {         log_debug(ZONE, "dnsrv: Adding lookup request for %s to pending queue.", p->host);         lnew = pmalloco(p->p, sizeof(_dns_packet_list));         lnew->packet = p;         lnew->stamp = time(NULL);         lnew->next = l;         ghash_put(d->packet_table, p->host, lnew);         return;    }    /* insert the packet into the packet_table using the hostname       as the key and send a request to the coprocess */    log_debug(ZONE, "dnsrv: Creating lookup request queue for %s", p->host);    l = pmalloco(p->p, sizeof(_dns_packet_list));    l->packet = p;    l->stamp  = time(NULL);    ghash_put(d->packet_table, p->host, l);

⌨️ 快捷键说明

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