[cvs] / netsukuku / src / andns_snsd.c Repository:
ViewVC logotype

View of /netsukuku/src/andns_snsd.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.20 - (download) (as text) (annotate)
Sun Mar 18 01:27:51 2007 UTC (3 years, 5 months ago) by efphe
Branch: MAIN
CVS Tags: HEAD
Changes since 1.19: +5 -5 lines
ntkresolv uses now andns_shared functions. general dbg.
    1 #include "includes.h"
    2 
    3 #include "llist.c"
    4 #include "andns_snsd.h"
    5 #include "err_errno.h"
    6 #include "andna.h"
    7 #include "log.h"
    8 
    9 
   10 
   11   /* h2ip functions */
   12 
   13 /*
   14  * Given a a hostname hash, makes a resolution
   15  * call (service=0) and search the main ip entry,
   16  * storing it to snsd_node dst.
   17  *
   18  * Returns:
   19  *  0
   20  *  -1
   21  */
   22 int snsd_main_ip(u_int *hname_hash,snsd_node *dst)
   23 {
   24   snsd_service *ss;
   25   snsd_prio *sp;
   26   snsd_node *sn;
   27   int records;
   28 
   29   ss=andna_resolve_hash(hname_hash,0,0,&records);
   30   if (!ss)
   31     err_ret(ERR_SNDMRF,-1);
   32   if (!(sp=ss->prio)) {
   33     goto destroy_return;
   34   }
   35   list_for(sp) {
   36     sn=sp->node;
   37     list_for(sn)
   38       if (sn->flags & SNSD_NODE_MAIN_IP) {
   39         memcpy(dst,sn,sizeof(snsd_node));
   40         snsd_service_llist_del(&ss);
   41         return 0;
   42       }
   43   }
   44   goto destroy_return;
   45 destroy_return:
   46   snsd_service_llist_del(&ss);
   47   err_ret(ERR_SNDMRF,-1);
   48 }
   49 
   50 /*
   51  * Convert a snsd_node to a binary ip.
   52  * If snsd_node does not contain a ip, but a hostname hash,
   53  * calls another resolution with service=0.
   54  *
   55  * Returns:
   56  *  bytes writed
   57  *
   58  */
   59 int snsd_node_to_data(char *buf,snsd_node *sn,u_char prio,int iplen,int recursion)
   60 {
   61   int res;
   62   int family;
   63 
   64   if (recursion!=-1) {
   65     *buf|=sn->weight&0x3f;
   66     *(buf+1)|=prio;
   67   }
   68 
   69         if (! (sn->flags & SNSD_NODE_HNAME)) {
   70     *buf|=0x40;
   71     if (sn->flags & SNSD_NODE_MAIN_IP )
   72       *buf|=0x80;
   73                 memcpy(buf+2,sn->record,iplen);
   74     family=(iplen==4)?AF_INET:AF_INET6;
   75     inet_htonl((u_int*)(buf+2),family);
   76     return iplen+2;
   77         } else if (recursion) {
   78                 snsd_node snt;
   79                 res=snsd_main_ip(sn->record,&snt);
   80     if (!res) { /* I love recursion */
   81                   res=snsd_node_to_data(buf,&snt,prio,iplen,-1);
   82       return res;
   83     }
   84   }
   85   memcpy(buf+2,sn->record,ANDNS_HASH_HNAME_LEN);
   86   return ANDNS_HASH_HNAME_LEN+2;
   87 }
   88 
   89 /*
   90  * Converts a snsd_node struct to andns data.
   91  * data means a packed answer.
   92  * buf has to be ANDNS_MAX_ANSW_IP_LEN long.
   93  *
   94  * returns -1 on error, answer len otherwise.
   95  *
   96  *  O B S O L E T E
   97 
   98 size_t snsd_node_to_aansw(char *buf,snsd_node *sn,u_char prio,int iplen)
   99 {
  100   int res;
  101 
  102   res=snsd_node_to_data(buf+2,sn,iplen);
  103   if (res==-1) {
  104     error(err_str);
  105     return -1;
  106   }
  107   if (sn->flags & SNSD_NODE_MAIN_IP)
  108     *buf|=0x80;
  109   *buf++=sn->weight;
  110   *buf=prio;
  111   return 0;
  112 }
  113 */
  114 
  115 
  116 /*
  117  * Converts a snsd_prio list to andns data.
  118  * data means a set of contiguous answers ready
  119  * to be sent.
  120  *
  121  * Returns the number of bytes writed to buf.
  122  * The size is computable with iplen.
  123  *
  124  * buf has to be long enough, ie, you have to count node
  125  * in prio list and take ANDNS_MAX_ANSW_IP_LEN * n space.
  126  *
  127  */
  128 int snsd_prio_to_aansws(char *buf,snsd_prio *sp,int iplen,int recursion,int *count)
  129 {
  130   int res=0;
  131   snsd_node *sn;
  132   int c=0;
  133 
  134   if(!sp || !buf)
  135     return 0;
  136 
  137   sn=sp->node;
  138   list_for(sn) {
  139     res+=snsd_node_to_data(buf+res,sn,sp->prio,
  140       iplen,recursion);
  141     c++;
  142   }
  143   *count=c;
  144   return res;
  145 }
  146 
  147 int snsd_service_to_aansws(char *buf,snsd_service *ss,int iplen,int *count,int recursion)
  148 {
  149   int family,c=0;
  150   uint16_t service;
  151   uint8_t prio,proto;
  152   snsd_prio *sp;
  153   snsd_node *sn;
  154   char *rem;
  155   snsd_node snt;
  156 
  157   if (!ss || !buf)
  158     return 0;
  159   rem=buf;
  160 
  161   list_for(ss) {
  162     service=htons(ss->service);
  163     proto=ss->proto;
  164     sp=ss->prio;
  165     list_for(sp) {
  166       prio=sp->prio;
  167       sn=sp->node;
  168       list_for(sn) {
  169         if (sn->flags & SNSD_NODE_MAIN_IP)
  170           (*buf)|=0xc0;
  171         else if (sn->flags & SNSD_NODE_IP)
  172           (*buf)|=0x40;
  173         if (proto==ANDNS_SNSD_PROTO_UDP)
  174           (*buf)|=0x20;
  175         *buf++|=(sn->weight&0x1f);
  176         *buf++|=prio;
  177         memcpy(buf,&service,2);
  178         buf+=2;
  179         if (sn->flags & SNSD_NODE_MAIN_IP ||
  180             sn->flags & SNSD_NODE_IP ) {
  181                       memcpy(buf,sn->record,iplen);
  182           family=(iplen==4)?AF_INET:AF_INET6;
  183           inet_htonl((u_int*)buf,family);
  184           buf+=iplen;
  185         } else {
  186           if (recursion && !snsd_main_ip(sn->record,&snt)) {
  187             memcpy(buf,snt.record,iplen);
  188             *(buf-4)|=0x40;
  189             family=(iplen==4)?AF_INET:AF_INET6;
  190             inet_htonl((u_int*)buf,family);
  191             buf+=iplen;
  192           } else {
  193             memcpy(buf,sn->record, ANDNS_HASH_HNAME_LEN);
  194             buf+=ANDNS_HASH_HNAME_LEN;
  195           }
  196 /*          service=strlen((char*)sn->record);
  197           temp=htons(service);
  198           memcpy(buf,&temp,2);
  199           memcpy(buf+2,sn->record,service);
  200           buf+=ANDNS_HASH_HNAME_LEN;
  201           res=snsd_main_ip(sn->record,&snt);
  202           if (res) {
  203             buf-=4;
  204             continue;
  205           }
  206           memcpy(buf,snt.record,iplen);
  207           family=(iplen==4)?AF_INET:AF_INET6;
  208           inet_htonl((u_int*)buf,family);
  209           buf+=iplen; */
  210         }
  211         c++;
  212       }
  213     }
  214   }
  215   *count=c;
  216   return (int)(buf-rem);
  217 }
  218 
  219 
  220 
  221 /*
  222  * Given a dns_packet, this function add an answer to it
  223  * and returns 0;
  224  * Otherwise returns -1.
  225  */
  226 int snsd_node_to_dansw(dns_pkt *dp,snsd_node *sn,int iplen)
  227 {
  228   char temp[18];
  229   dns_pkt_a *dpa;
  230   snsd_node snt,*s;
  231   int res;
  232 
  233   if (!(sn->flags & SNSD_NODE_HNAME)) {
  234     if (!(res=snsd_main_ip(sn->record,&snt)))
  235       return -1;
  236     s=&snt;
  237   } else
  238     s=sn;
  239 
  240         memcpy(temp,sn->record,iplen);
  241         inet_htonl((u_int*)(temp),
  242     (iplen==4)?AF_INET:AF_INET6);
  243 
  244   dpa=DP_ADD_ANSWER(dp);
  245   dns_a_default_fill(dp,dpa);
  246   dpa->rdlength=iplen;
  247   memcpy(dpa->rdata,temp,iplen);
  248   return 0;
  249 }
  250 /*
  251  * Converts a snsd_prio struct, adding a set of answers to
  252  * the dns_packet dp.
  253  * Returns the number of answers added to dp.
  254  */
  255 int snsd_prio_to_dansws(dns_pkt *dp,snsd_prio *sp,int iplen)
  256 {
  257   int res=0;
  258   snsd_node *sn;
  259 
  260   sn=sp->node;
  261   list_for(sn)
  262     if (!snsd_node_to_dansw(dp,sn,iplen))
  263       res++;
  264   return res;
  265 }
  266 
  267 
  268 
  269   /* ip2h functions */
  270 
  271 /*
  272  * Converts a lcl_cache struct to a set of dns answers.
  273  * Returns the number of answers added.
  274  */
  275 int lcl_cache_to_dansws(dns_pkt *dp,lcl_cache *lc)
  276 {
  277   dns_pkt_a *dpa;
  278   int res=0;
  279 
  280   list_for(lc) {
  281     dpa=DP_ADD_ANSWER(dp);
  282     dns_a_default_fill(dp,dpa);
  283     strcpy(dpa->rdata,lc->hostname);
  284     res++;
  285   }
  286 
  287   if(lc)
  288     lcl_cache_free(lc);
  289 
  290   return res;
  291 }
  292 
  293 /*
  294  * Converts a lcl_cache to andns data.
  295  * Returns the number of bytes writed.
  296  */
  297 size_t lcl_cache_to_aansws(char *buf,lcl_cache *lc,int *count)
  298 {
  299   uint16_t slen;
  300   size_t ret=0;
  301   int lcount=0;
  302   lcl_cache *lcl=lc;
  303 
  304   list_for(lcl) {
  305     slen=strlen(lc->hostname);
  306     ret+=2+slen;
  307     slen=htons(slen);
  308     memcpy(buf,&slen,2);
  309     buf+=2;
  310     strcpy(buf,lc->hostname);
  311     lcount++;
  312   }
  313   *count=lcount;
  314   lcl_cache_free(lc);
  315   return ret;
  316 }

alpt (at) freaknet (dot) org
ViewVC Help
Powered by ViewVC 1.1-dev