From e576be5096ae358bebe2e9b6ad07c49f74aef616 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 8 Nov 1998 15:13:15 +0000 Subject: [PATCH 1/1] Rearrangement more or less sorted, back to trying to get it to compile. --- client/adnstest.c | 22 ++- regress/junk | 6 + src/Makefile | 27 +++- src/Makefile.in | 27 +++- src/adns.h | 20 +++ src/event.c | 24 ++- src/general.c | 150 +++++++++++++++++++ src/internal.h | 86 +++++++++-- src/parse.c | 46 +++--- src/query.c | 362 +++++++++++++++++++++++++--------------------- src/reply.c | 24 ++- src/setup.c | 121 +++------------- src/submit.c | 186 ------------------------ src/transmit.c | 181 +++++++++++++++++++++++ src/types.c | 22 ++- 15 files changed, 798 insertions(+), 506 deletions(-) create mode 100644 regress/junk create mode 100644 src/general.c delete mode 100644 src/submit.c create mode 100644 src/transmit.c diff --git a/client/adnstest.c b/client/adnstest.c index 2f9e525..94037b2 100644 --- a/client/adnstest.c +++ b/client/adnstest.c @@ -1,4 +1,24 @@ -/**/ +/* + * dtest.c + * - simple test program, not part of the library + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include #include diff --git a/regress/junk b/regress/junk new file mode 100644 index 0000000..7992f49 --- /dev/null +++ b/regress/junk @@ -0,0 +1,6 @@ + +#include +#include +#include + +#include diff --git a/src/Makefile b/src/Makefile index 2719f33..4096d84 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,19 @@ +# This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + CC=gcc $(WARNS) $(WERROR) $(OPTIMISE) $(DEBUG) DEBUG=-g OPTIMISE=-O2 @@ -5,14 +21,15 @@ WARNS= -Wall -Wmissing-prototypes -Wwrite-strings -Wstrict-prototypes \ -Wcast-qual -Wpointer-arith WERROR=-Werror +LIBOBJS= event.o query.o setup.o transmit.o general.o reply.o parse.o +ALLOBJS= $(LIBOBJS) dtest.o + all: dtest -dtest: dtest.o event.o query.o setup.o submit.o reply.o parse.o +dtest: $(ALLOBJS) clean: rm -f dtest *.o -dtest.o: adns.h - -event.o query.o setup.o submit.o reply.o parse.o: internal.h adns.h - +dtest.o: adns.h +$(LIBOBJS): adns.h internal.h diff --git a/src/Makefile.in b/src/Makefile.in index 2719f33..4096d84 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,3 +1,19 @@ +# This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + CC=gcc $(WARNS) $(WERROR) $(OPTIMISE) $(DEBUG) DEBUG=-g OPTIMISE=-O2 @@ -5,14 +21,15 @@ WARNS= -Wall -Wmissing-prototypes -Wwrite-strings -Wstrict-prototypes \ -Wcast-qual -Wpointer-arith WERROR=-Werror +LIBOBJS= event.o query.o setup.o transmit.o general.o reply.o parse.o +ALLOBJS= $(LIBOBJS) dtest.o + all: dtest -dtest: dtest.o event.o query.o setup.o submit.o reply.o parse.o +dtest: $(ALLOBJS) clean: rm -f dtest *.o -dtest.o: adns.h - -event.o query.o setup.o submit.o reply.o parse.o: internal.h adns.h - +dtest.o: adns.h +$(LIBOBJS): adns.h internal.h diff --git a/src/adns.h b/src/adns.h index 29cf815..7268381 100644 --- a/src/adns.h +++ b/src/adns.h @@ -4,6 +4,23 @@ * * $Id$ */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #ifndef ADNS_H_INCLUDED #define ADNS_H_INCLUDED @@ -220,6 +237,9 @@ int adns_wait(adns_state ads, void adns_cancel(adns_state ads, adns_query query); int adns_finish(adns_state); +/* You may call this even if you have queries outstanding; + * they will be cancelled. + */ int adns_callback(adns_state, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds); diff --git a/src/event.c b/src/event.c index 7a28e01..dcf0adb 100644 --- a/src/event.c +++ b/src/event.c @@ -1,4 +1,26 @@ -/**/ +/* + * event.c + * - event loop core + * - TCP connection management + * - user-visible check/wait and event-loop-related functions + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include #include diff --git a/src/general.c b/src/general.c new file mode 100644 index 0000000..7c42eb6 --- /dev/null +++ b/src/general.c @@ -0,0 +1,150 @@ +/* + * general.c + * - diagnostic functions + * - vbuf handling + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "internal.h" + +/* Core diagnostic functions */ + +void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, + int serv, const char *fmt, adns_query qu, va_list al) { + const char *bef, *aft; + vbuf vb; + if (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent))) return; + + fprintf(stderr,"adns%s: ",pfx); + + vfprintf(stderr,fmt,al); + + bef= " ("; + aft= "\n"; + + if (qu && qu->query_dgram) { + adns__vbuf_init(&vb); + fprintf(stderr,"%sQNAME=%s, QTYPE=%s", + bef, + adns__diag_domain(ads,-1,0,&vb,qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), + qu->typei ? qu->typei->name : ""); + bef=", "; aft=")\n"; + } + + if (serv>=0) { + fprintf(stderr,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr)); + bef=", "; aft=")\n"; + } + + fputs(aft,stderr); +} + +void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { + va_list al; + + va_start(al,fmt); + adns__vdiag(ads," debug",0,serv,qu,fmt,al); + va_end(al); +} + +void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { + va_list al; + + va_start(al,fmt); + adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al); + va_end(al); +} + +void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { + va_list al; + + va_start(al,fmt); + adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al); + va_end(al); +} + +/* vbuf functions */ + +void adns__vbuf_init(vbuf *vb) { + vb->used= vb->avail= 0; vb->buf= 0; +} + +int adns__vbuf_ensure(vbuf *vb, int want) { + void *nb; + + if (vb->avail >= want) return 1; + nb= realloc(vb->buf,want); if (!nb) return 0; + vb->buf= nb; + vb->avail= want; + return 1; +} + +void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) { + memcpy(vb->buf+vb->used,data,len); + vb->used+= len; +} + +int adns__vbuf_append(vbuf *vb, const byte *data, int len) { + int newlen; + void *nb; + + newlen= vb->used+len; + if (vb->avail < newlen) { + newlen <<= 1; + nb= realloc(vb->buf,newlen); + if (!nb) { newlen >>= 1; nb= realloc(vb->buf,newlen); } + if (!nb) return 0; + vb->buf= nb; + vb->avail= newlen; + } + adns__vbuf_appendq(vb,data,len); + return 1; +} + +/* Additional diagnostic functions */ + +const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, + int flags, const byte *dgram, int dglen, int cbyte) { + adns_status st; + + st= adns__parse_domain(ads,serv,vb,qu->flags, dgram,dglen, &cbyte,dglen); + if (st == adns_s_nomemory) { + return ""; + } + if (st) { + vb->used= 0; + if (!(adns__vbuf_appendstr(vb,"") && + adns__vbuf_append(vb,"",1))) { + return ""; + } + } + if (!vb.used) { + adns__vbuf_appendstr(vb,""); + adns__vbuf_append(vb,"",1); + } + return vb->buf; +} + +const char *adns_strerror(adns_status st) { + static char buf[100]; + snprintf(buf,sizeof(buf),"code %d",st); + return buf; +} diff --git a/src/internal.h b/src/internal.h index 58d4a4c..61f2ff7 100644 --- a/src/internal.h +++ b/src/internal.h @@ -1,4 +1,26 @@ -/**/ +/* + * internal.h + * - declarations of private objects with external linkage (adns__*) + * - definitons of internal macros + * - comments regarding library data structures + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #ifndef ADNS_INTERNAL_H_INCLUDED #define ADNS_INTERNAL_H_INCLUDED @@ -200,6 +222,10 @@ struct adns__state { /* From setup.c: */ +int adns__setnonblock(adns_state ads, int fd); /* => errno value */ + +/* From general.c: */ + void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, int serv, adns_query qu, const char *fmt, va_list al); @@ -218,9 +244,46 @@ void adns__vbuf_appendq(vbuf *vb, const byte *data, int len); void adns__vbuf_init(vbuf *vb); void adns__vbuf_free(vbuf *vb); -int adns__setnonblock(adns_state ads, int fd); /* => errno value */ +const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, + int flags, const byte *dgram, int dglen, int cbyte); +/* Unpicks a domain in a datagram and returns a string suitable for + * printing it as. Never fails - if an error occurs, it will + * return some kind of string describing the error. + * + * serv may be -1, qu may be 0. vb must have been initialised, + * and will be left in an arbitrary consistent state. + * + * Returns either vb->buf, or a pointer to a string literal. Do not modify + * vb before using the return value. + */ + +/* From transmit.c: */ -/* From submit.c: */ +adns_status adns__mkquery(adns_state ads, vbuf *vb, + const char *owner, int ol, int *id_r, + const typeinfo *typei, adns_queryflags flags); +/* Assembles a query packet in vb, and returns id at *id_r. */ + +void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now); +/* Query must be in state tcpwait/timew; it will be moved to a new state + * if possible and no further processing can be done on it for now. + * (Resulting state is one of tcpwait/timew (if server not connected), + * tcpsent/timew, child/childw or done/output.) + * + * adns__tcp_tryconnect should already have been called - _tcp + * will only use an existing connection (if there is one), which it + * may break. If the conn list lost then the caller is responsible for any + * reestablishment and retry. + */ + +void adns__query_udp(adns_state ads, adns_query qu, struct timeval now); +/* Query must be in state udp/NONE; it will be moved to a new state, + * and no further processing can be done on it for now. + * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected), + * tcpsent/timew, child/childw or done/output.) + */ + +/* From query.c: */ int adns__internal_submit(adns_state ads, adns_query *query_r, adns_rrtype type, vbuf *qumsg_vb, int id, @@ -261,18 +324,6 @@ void *adns__alloc_final(adns_query qu, size_t sz); void adns__makefinal_block(adns_query qu, void **blpp, size_t sz); void adns__makefinal_str(adns_query qu, char **strp); -/* From query.c: */ - -void adns__query_udp(adns_state ads, adns_query qu, struct timeval now); -void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now); -adns_status adns__mkquery(adns_state ads, vbuf *vb, - const char *owner, int ol, int *id_r, - const typeinfo *typei, adns_queryflags flags); -/* Assembles a query packet in vb, and returns id at *id_r. */ - -void adns__query_ok(adns_state ads, adns_query qu); -void adns__query_fail(adns_state ads, adns_query qu, adns_status stat); - void adns__reset_cnameonly(adns_state ads, adns_query qu); /* Resets all of the memory management stuff etc. to * take account of only the CNAME. Used when we find an error somewhere @@ -280,6 +331,9 @@ void adns__reset_cnameonly(adns_state ads, adns_query qu); * when we're halfway through RRs in a datagram and discover that we * need to retry the query. */ + +void adns__query_done(adns_state ads, adns_query qu); +void adns__query_fail(adns_state ads, adns_query qu, adns_status stat); /* From reply.c: */ @@ -382,7 +436,9 @@ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len); void adns__tcp_broken(adns_state ads, const char *what, const char *why); void adns__tcp_tryconnect(adns_state ads, struct timeval now); + void adns__autosys(adns_state ads, struct timeval now); +/* Make all the system calls we want to if the application wants us to. */ /* Useful static inline functions: */ diff --git a/src/parse.c b/src/parse.c index 9691dcc..bf04d4d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1,4 +1,24 @@ -/**/ +/* + * parse.c + * - parsing assistance functions (mainly for domains inside datagrams) + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include "internal.h" @@ -120,30 +140,6 @@ adns_status adns__parse_domain(adns_state ads, int serv, vbuf *vb, int flags, return adns_s_ok; } -const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, - int flags, const byte *dgram, int dglen, int cbyte) { - adns_status st; - - st= adns__parse_domain(ads,serv,vb,qu->flags, dgram,dglen, &cbyte,dglen); - if (st == adns_s_nomemory) { - return ""; - } - if (st) { - vb->used= 0; - if (!(adns__vbuf_appendstr(vb,"") && - adns__vbuf_append(vb,"",1))) { - return ""; - } - } - if (!vb.used) { - adns__vbuf_appendstr(vb,""); - adns__vbuf_append(vb,"",1); - } - return vb->buf; -} - adns_status adns__findrr(adns_state ads, int serv, const byte *dgram, int dglen, int *cbyte_io, int *type_r, int *class_r, int *rdlen_r, int *rdstart_r, diff --git a/src/query.c b/src/query.c index 890757e..7f65bc1 100644 --- a/src/query.c +++ b/src/query.c @@ -1,183 +1,200 @@ -/**/ - -#include -#include -#include - -#include +/* + * query.c + * - overall query management (allocation, completion) + * - per-query memory management + * - query submission and cancellation (user-visible and internal) + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include "internal.h" -adns_status adns__mkquery(adns_state ads, vbuf *vb, - const char *owner, int ol, int *id_r, - const typeinfo *typei, adns_queryflags flags) { - int ll, c, nlabs, id; - byte label[255], *rqp; - const char *p, *pe; - -#define MKQUERY_ADDB(b) *rqp++= (b) -#define MKQUERY_ADDW(w) (MKQUERY_ADDB(((w)>>8)&0x0ff), MKQUERY_ADDB((w)&0x0ff)) - - vb->used= 0; - if (!adns__vbuf_ensure(vb,DNS_HDRSIZE+strlen(owner)+1+5)) - return adns_s_nolocalmem; - rqp= vb->buf; - - *id_r= id= (ads->nextid++) & 0x0ffff; - - MKQUERY_ADDW(id); - MKQUERY_ADDB(0x01); /* QR=Q(0), OPCODE=QUERY(0000), !AA, !TC, RD */ - MKQUERY_ADDB(0x00); /* !RA, Z=000, RCODE=NOERROR(0000) */ - MKQUERY_ADDW(1); /* QDCOUNT=1 */ - MKQUERY_ADDW(0); /* ANCOUNT=0 */ - MKQUERY_ADDW(0); /* NSCOUNT=0 */ - MKQUERY_ADDW(0); /* ARCOUNT=0 */ - p= owner; pe= owner+ol; - nlabs= 0; - if (!*p) return adns_s_invaliddomain; - do { - ll= 0; - while (p!=pe && (c= *p++)!='.') { - if (c=='\\') { - if (!(flags & adns_qf_anyquote)) return adns_s_invaliddomain; - if (ctype_digit(p[0])) { - if (ctype_digit(p[1]) && ctype_digit(p[2])) { - c= (*p++ - '0')*100 + (*p++ - '0')*10 + (*p++ - '0'); - if (c >= 256) return adns_s_invaliddomain; - } else { - return adns_s_invaliddomain; - } - } else if (!(c= *p++)) { - return adns_s_invaliddomain; - } - } - if (!(flags & adns_qf_anyquote)) { - if (ctype_digit(c) || c == '-') { - if (!ll) return adns_s_invaliddomain; - } else if (!ctype_alpha(c)) { - return adns_s_invaliddomain; - } - } - if (ll == sizeof(label)) return adns_s_invaliddomain; - label[ll++]= c; - } - if (!ll) return adns_s_invaliddomain; - if (nlabs++ > 63) return adns_s_invaliddomain; - MKQUERY_ADDB(ll); - memcpy(rqp,label,ll); rqp+= ll; - } while (p!=pe); - - MKQUERY_ADDB(0); - MKQUERY_ADDW(typei->type & adns__rrt_typemask); /* QTYPE */ - MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */ - - vb->used= rqp - vb->buf; - assert(vb->used <= vb->avail); - - return adns_s_ok; -} +#include +#include +#include -void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) { - /* Query must be in state tcpwait/timew; it will be moved to a new state - * if possible and no further processing can be done on it for now. - * (Resulting state is one of tcpwait/timew (if server not connected), - * tcpsent/timew, child/childw or done/output.) - * - * adns__tcp_tryconnect should already have been called - _tcp - * will only use an existing connection (if there is one), which it - * may break. If the conn list lost then the caller is responsible for any - * reestablishment and retry. - */ - byte length[2]; - struct iovec iov[2]; - int wr, r; +#include - if (ads->tcpstate != server_ok) return; +#include "internal.h" - length[0]= (qu->query_dglen&0x0ff00U) >>8; - length[1]= (qu->query_dglen&0x0ff); +int adns__internal_submit(adns_state ads, adns_query *query_r, + adns_rrtype type, vbuf *qumsg_vb, int id, + adns_queryflags flags, struct timeval now, + adns_status failstat, const qcontext *ctx) { + adns_query qu; + adns_status stat; + int ol, id, r; + struct timeval now; + const typeinfo *typei; + adns_query qu; + + qu= malloc(sizeof(*qu)); if (!qu) goto x_nomemory; + qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) goto x_freequ_nomemory; + + qu->state= query_udp; + qu->back= qu->next= qu->parent= 0; + LIST_INIT(qu->children); + qu->siblings.next= qu->siblings.back= 0; + qu->allocations= 0; + qu->interim_allocd= 0; + qu->perm_used= 0; + + qu->typei= adns__findtype(type); + adns__vbuf_init(&qu->vb); + + qu->cname_dgram= 0; + qu->cname_dglen= qu->cname_begin= 0; - if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->query_dglen+2)) return; - - timevaladd(&now,TCPMS); - qu->timeout= now; - qu->state= query_tcpsent; - LIST_LINK_TAIL(ads->timew,qu); + qu->id= id; + qu->flags= flags; + qu->udpretries= 0; + qu->udpnextserver= 0; + qu->udpsent= qu->tcpfailed= 0; + timerclear(&qu->timeout); + memcpy(&qu->context,ctx,sizeof(qu->context)); + memcpy(qu->owner,owner,ol); qu->owner[ol]= 0; + + qu->answer->status= adns_s_ok; + qu->answer->cname= 0; + qu->answer->type= type; + qu->answer->nrrs= 0; + qu->answer->rrs= 0; - if (ads->tcpsend.used) { - wr= 0; + if (qu->typei) { + qu->answer->rrsz= qu->rrsz; } else { - iov[0].iov_base= length; - iov[0].iov_len= 2; - iov[1].iov_base= qu->query_dgram; - iov[1].iov_len= qu->query_dglen; - wr= writev(ads->tcpsocket,iov,2); - if (wr < 0) { - if (!(errno == EAGAIN || errno == EINTR || errno == ENOSPC || - errno == ENOBUFS || errno == ENOMEM)) { - adns__tcp_broken(ads,"write",strerror(errno)); - return; - } - wr= 0; - } + qu->answer->rrsz= -1; + failstat= adns_s_notimplemented; } + + *query_r= qu; - if (wr<2) { - r= adns__vbuf_append(&ads->tcpsend,length,2-wr); assert(r); - wr= 0; - } else { - wr-= 2; + qu->query_dgram= malloc(qumsg_vb->used); + if (!qu->query_dgram) { + adns__query_fail(ads,qu,adns_s_nomemory); + return; } - if (wrquery_dglen) { - r= adns__vbuf_append(&ads->tcpsend,qu->query_dgram+wr,qu->query_dglen-wr); assert(r); + memcpy(qu->query_dgram,qumsg_vb->buf,qumsg_vb->used); + qu->vb= *qumsg_vb; + adns__vbuf_init(qumsg_vb); + + if (failstat) { + adns__query_fail(ads,qu,failstat); + return; } + adns__query_udp(ads,qu,now); + adns__autosys(ads,now); + + return 0; + + x_freequ_nomemory: + free(qu); + x_nomemory: + free(query_dgram); + return adns_s_nomemory; } -static void query_usetcp(adns_state ads, adns_query qu, struct timeval now) { - timevaladd(&now,TCPMS); - qu->timeout= now; - qu->state= query_tcpwait; - LIST_LINK_TAIL(ads->timew,qu); - adns__query_tcp(ads,qu,now); - adns__tcp_tryconnect(ads,now); +int adns_submit(adns_state ads, + const char *owner, + adns_rrtype type, + adns_queryflags flags, + void *context, + adns_query *query_r) { + qcontext ctx; + int id; + vbuf vb; + + ctx.ext= context; + r= gettimeofday(&now,0); if (r) return errno; + id= 0; + + adns__vbuf_init(&vb); + + ol= strlen(owner); + if (ol<=1 || ol>DNS_MAXDOMAIN+1) { stat= adns_s_invaliddomain; goto xit; } + + if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; } + + stat= adns__mkquery(ads,&vb, &id, owner,ol, typei,flags); + + xit: + return adns__internal_submit(ads,query_r, type,&vb,id, flags,now, stat,&ctx); } -void adns__query_udp(adns_state ads, adns_query qu, struct timeval now) { - /* Query must be in state udp/NONE; it will be moved to a new state, - * and no further processing can be done on it for now. - * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected), - * tcpsent/timew, child/childw or done/output.) - */ - struct sockaddr_in servaddr; - int serv, r; +int adns_synchronous(adns_state ads, + const char *owner, + adns_rrtype type, + adns_queryflags flags, + adns_answer **answer_r) { + adns_query qu; + int r; + + r= adns_submit(ads,owner,type,flags,0,&qu); + if (r) return r; - assert(qu->state == query_udp); - if ((qu->flags & adns_qf_usevc) || (qu->query_dglen > DNS_MAXUDP)) { - query_usetcp(ads,qu,now); - return; - } + do { + r= adns_wait(ads,&qu,answer_r,0); + } while (r==EINTR); + if (r) adns_cancel(ads,qu); + return r; +} - if (qu->udpretries >= UDPMAXRETRIES) { - adns__query_fail(ads,qu,adns_s_timeout); - return; +void adns_cancel(adns_state ads, adns_query query) { + abort(); /* fixme */ +} + +void *adns__alloc_interim(adns_state ads, adns_query qu, size_t sz) { + allocnode *an; + + assert(!qu->final_allocspace); + sz= MEM_ROUND(sz); + an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz)); + if (!an) { + adns__query_fail(ads,qu,adns_s_nolocalmem); + return 0; } + qu->permalloclen += sz; + an->next= qu->allocations; + qu->allocations= an; + return (byte*)an + MEM_ROUND(sizeof(*an)); +} - serv= qu->udpnextserver; - memset(&servaddr,0,sizeof(servaddr)); - servaddr.sin_family= AF_INET; - servaddr.sin_addr= ads->servers[serv].addr; - servaddr.sin_port= htons(DNS_PORT); - - r= sendto(ads->udpsocket,qu->query_dgram,qu->query_dglen,0,&servaddr,sizeof(servaddr)); - if (r<0 && errno == EMSGSIZE) { query_usetcp(ads,qu,now); return; } - if (r<0) adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno)); - - timevaladd(&now,UDPRETRYMS); - qu->timeout= now; - qu->udpsent |= (1<udpnextserver= (serv+1)%ads->nservers; - qu->udpretries++; - LIST_LINK_TAIL(ads->timew,qu); +void *adns__alloc_final(adns_query qu, size_t sz) { + /* When we're in the _final stage, we _subtract_ from interim_alloc'd + * each allocation, and use final_allocspace to point to the next free + * bit. + */ + void *rp; + + sz= MEM_ROUND(sz); + rp= qu->final_allocspace; + assert(rp); + qu->interim_allocd -= sz; + assert(qu->interim_allocd>=0); + qu->final_allocspace= (byte*)rp + sz; + return rp; +} + +void adns__reset_cnameonly(adns_state ads, adns_query qu) { + assert(qu->final_allocspace); + qu->answer->nrrs= 0; + qu->answer->rrs= 0; + qu->interim_allocd= qu->answer->cname ? MEM_ROUND(strlen(qu->answer->cname)+1) : 0; } static void adns__query_done(adns_state ads, adns_query qu) { @@ -205,15 +222,28 @@ static void adns__query_done(adns_state ads, adns_query qu) { LIST_LINK_TAIL(ads->output,qu); } -void adns__reset_cnameonly(adns_state ads, adns_query qu) { - assert(qu->final_allocspace); - qu->answer->nrrs= 0; - qu->answer->rrs= 0; - qu->interim_allocd= qu->answer->cname ? MEM_ROUND(strlen(qu->answer->cname)+1) : 0; -} - void adns__query_fail(adns_state ads, adns_query qu, adns_status stat) { adns__reset_cnameonly(ads,qu); qu->answer->status= stat; adns__query_done(ads,qu); } + +void adns__makefinal_str(adns_query qu, char **strp) { + int l; + char *before, *after; + + before= *strp; + l= strlen(before)+1; + after= adns__alloc_final(qu,l); + memcpy(after,before,l); + *strp= after; +} + +void adns__makefinal_block(adns__query qu, void **blpp, size_t sz) { + void *after; + + after= adns__alloc_final(qu,sz); + memcpy(after,*blpp,sz); + *blpp= after; +} + diff --git a/src/reply.c b/src/reply.c index 198218e..337d3f8 100644 --- a/src/reply.c +++ b/src/reply.c @@ -1,4 +1,24 @@ -/**/ +/* + * reply.c + * - main handling and parsing routine for received datagrams + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include "internal.h" @@ -254,7 +274,7 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen, adns__query_finish(ads,qu,adns_s_ok); return; -x_truncated: + x_truncated: if (!flg_tc) { adns__diag(ads,serv,qu,"server sent datagram which points outside itself"); adns__query_fail(ads,qu,adns_s_serverfaulty); diff --git a/src/setup.c b/src/setup.c index 7ea5389..78b8fb3 100644 --- a/src/setup.c +++ b/src/setup.c @@ -1,4 +1,25 @@ -/**/ +/* + * setup.c + * - configuration file parsing + * - management of global state + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include #include @@ -11,98 +32,6 @@ #include "internal.h" -void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, - int serv, const char *fmt, adns_query qu, va_list al) { - const char *bef, *aft; - vbuf vb; - if (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent))) return; - - fprintf(stderr,"adns%s: ",pfx); - - vfprintf(stderr,fmt,al); - - bef= " ("; - aft= "\n"; - - if (qu && qu->query_dgram) { - adns__vbuf_init(&vb); - fprintf(stderr,"%sQNAME=%s, QTYPE=%s", - bef, - adns__diag_domain(ads,-1,0,&vb,qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), - qu->typei ? qu->typei->name : ""); - bef=", "; aft=")\n"; - } - - if (serv>=0) { - fprintf(stderr,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr)); - bef=", "; aft=")\n"; - } - - fputs(aft,stderr); -} - -void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { - va_list al; - - va_start(al,fmt); - adns__vdiag(ads," debug",0,serv,qu,fmt,al); - va_end(al); -} - -void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { - va_list al; - - va_start(al,fmt); - adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al); - va_end(al); -} - -void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { - va_list al; - - va_start(al,fmt); - adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al); - va_end(al); -} - - -void adns__vbuf_init(vbuf *vb) { - vb->used= vb->avail= 0; vb->buf= 0; -} - -int adns__vbuf_ensure(vbuf *vb, int want) { - void *nb; - - if (vb->avail >= want) return 1; - nb= realloc(vb->buf,want); if (!nb) return 0; - vb->buf= nb; - vb->avail= want; - return 1; -} - -void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) { - memcpy(vb->buf+vb->used,data,len); - vb->used+= len; -} - -int adns__vbuf_append(vbuf *vb, const byte *data, int len) { - int newlen; - void *nb; - - newlen= vb->used+len; - if (vb->avail < newlen) { - newlen <<= 1; - nb= realloc(vb->buf,newlen); - if (!nb) { newlen >>= 1; nb= realloc(vb->buf,newlen); } - if (!nb) return 0; - vb->buf= nb; - vb->avail= newlen; - } - adns__vbuf_appendq(vb,data,len); - return 1; -} - - static void addserver(adns_state ads, struct in_addr addr) { int i; struct server *ss; @@ -323,9 +252,3 @@ int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { int adns_finish(adns_state ads) { abort(); /* fixme */ } - -const char *adns_strerror(adns_status st) { - static char buf[100]; - snprintf(buf,sizeof(buf),"code %d",st); - return buf; -} diff --git a/src/submit.c b/src/submit.c deleted file mode 100644 index 197381d..0000000 --- a/src/submit.c +++ /dev/null @@ -1,186 +0,0 @@ -/**/ - -#include -#include -#include - -#include - -#include "internal.h" - -int adns__internal_submit(adns_state ads, adns_query *query_r, - adns_rrtype type, vbuf *qumsg_vb, int id, - adns_queryflags flags, struct timeval now, - adns_status failstat, const qcontext *ctx) { - adns_query qu; - adns_status stat; - int ol, id, r; - struct timeval now; - const typeinfo *typei; - adns_query qu; - - qu= malloc(sizeof(*qu)); if (!qu) goto x_nomemory; - qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) goto x_freequ_nomemory; - - qu->state= query_udp; - qu->back= qu->next= qu->parent= 0; - LIST_INIT(qu->children); - qu->siblings.next= qu->siblings.back= 0; - qu->allocations= 0; - qu->interim_allocd= 0; - qu->perm_used= 0; - - qu->typei= adns__findtype(type); - adns__vbuf_init(&qu->vb); - - qu->cname_dgram= 0; - qu->cname_dglen= qu->cname_begin= 0; - - qu->id= id; - qu->flags= flags; - qu->udpretries= 0; - qu->udpnextserver= 0; - qu->udpsent= qu->tcpfailed= 0; - timerclear(&qu->timeout); - memcpy(&qu->context,ctx,sizeof(qu->context)); - memcpy(qu->owner,owner,ol); qu->owner[ol]= 0; - - qu->answer->status= adns_s_ok; - qu->answer->cname= 0; - qu->answer->type= type; - qu->answer->nrrs= 0; - qu->answer->rrs= 0; - - if (qu->typei) { - qu->answer->rrsz= qu->rrsz; - } else { - qu->answer->rrsz= -1; - failstat= adns_s_notimplemented; - } - - *query_r= qu; - - qu->query_dgram= malloc(qumsg_vb->used); - if (!qu->query_dgram) { - adns__query_fail(ads,qu,adns_s_nomemory); - return; - } - memcpy(qu->query_dgram,qumsg_vb->buf,qumsg_vb->used); - qu->vb= *qumsg_vb; - adns__vbuf_init(qumsg_vb); - - if (failstat) { - adns__query_fail(ads,qu,failstat); - return; - } - adns__query_udp(ads,qu,now); - adns__autosys(ads,now); - - return 0; - - x_freequ_nomemory: - free(qu); - x_nomemory: - free(query_dgram); - return adns_s_nomemory; -} - -int adns_submit(adns_state ads, - const char *owner, - adns_rrtype type, - adns_queryflags flags, - void *context, - adns_query *query_r) { - qcontext ctx; - int id; - vbuf vb; - - ctx.ext= context; - r= gettimeofday(&now,0); if (r) return errno; - id= 0; - - adns__vbuf_init(&vb); - - ol= strlen(owner); - if (ol<=1 || ol>DNS_MAXDOMAIN+1) { stat= adns_s_invaliddomain; goto xit; } - - if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; } - - stat= adns__mkquery(ads,&vb, &id, owner,ol, typei,flags); - - xit: - return adns__internal_submit(ads,query_r, type,&vb,id, flags,now, stat,&ctx); -} - -int adns_synchronous(adns_state ads, - const char *owner, - adns_rrtype type, - adns_queryflags flags, - adns_answer **answer_r) { - adns_query qu; - int r; - - r= adns_submit(ads,owner,type,flags,0,&qu); - if (r) return r; - - do { - r= adns_wait(ads,&qu,answer_r,0); - } while (r==EINTR); - if (r) adns_cancel(ads,qu); - return r; -} - -void adns_cancel(adns_state ads, adns_query query) { - abort(); /* fixme */ -} - -void adns__makefinal_str(adns_query qu, char **strp) { - int l; - char *before, *after; - - before= *strp; - l= strlen(before)+1; - after= adns__alloc_final(qu,l); - memcpy(after,before,l); - *strp= after; -} - -void adns__makefinal_block(adns__query qu, void **blpp, size_t sz) { - void *after; - - after= adns__alloc_final(qu,sz); - memcpy(after,*blpp,sz); - *blpp= after; -} - -void *adns__alloc_interim(adns_state ads, adns_query qu, size_t sz) { - allocnode *an; - - assert(!qu->final_allocspace); - sz= MEM_ROUND(sz); - an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz)); - if (!an) { - adns__query_fail(ads,qu,adns_s_nolocalmem); - return 0; - } - qu->permalloclen += sz; - an->next= qu->allocations; - qu->allocations= an; - return (byte*)an + MEM_ROUND(sizeof(*an)); -} - -void *adns__alloc_final(adns_query qu, size_t sz) { - /* When we're in the _final stage, we _subtract_ from interim_alloc'd - * each allocation, and use final_allocspace to point to the next free - * bit. - */ - void *rp; - - sz= MEM_ROUND(sz); - rp= qu->final_allocspace; - assert(rp); - qu->interim_allocd -= sz; - assert(qu->interim_allocd>=0); - qu->final_allocspace= (byte*)rp + sz; - return rp; -} diff --git a/src/transmit.c b/src/transmit.c new file mode 100644 index 0000000..2633bdc --- /dev/null +++ b/src/transmit.c @@ -0,0 +1,181 @@ +/* + * transmit.c + * - construct queries + * - send queries + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "internal.h" + +adns_status adns__mkquery(adns_state ads, vbuf *vb, + const char *owner, int ol, int *id_r, + const typeinfo *typei, adns_queryflags flags) { + int ll, c, nlabs, id; + byte label[255], *rqp; + const char *p, *pe; + +#define MKQUERY_ADDB(b) *rqp++= (b) +#define MKQUERY_ADDW(w) (MKQUERY_ADDB(((w)>>8)&0x0ff), MKQUERY_ADDB((w)&0x0ff)) + + vb->used= 0; + if (!adns__vbuf_ensure(vb,DNS_HDRSIZE+strlen(owner)+1+5)) + return adns_s_nolocalmem; + rqp= vb->buf; + + *id_r= id= (ads->nextid++) & 0x0ffff; + + MKQUERY_ADDW(id); + MKQUERY_ADDB(0x01); /* QR=Q(0), OPCODE=QUERY(0000), !AA, !TC, RD */ + MKQUERY_ADDB(0x00); /* !RA, Z=000, RCODE=NOERROR(0000) */ + MKQUERY_ADDW(1); /* QDCOUNT=1 */ + MKQUERY_ADDW(0); /* ANCOUNT=0 */ + MKQUERY_ADDW(0); /* NSCOUNT=0 */ + MKQUERY_ADDW(0); /* ARCOUNT=0 */ + p= owner; pe= owner+ol; + nlabs= 0; + if (!*p) return adns_s_invaliddomain; + do { + ll= 0; + while (p!=pe && (c= *p++)!='.') { + if (c=='\\') { + if (!(flags & adns_qf_anyquote)) return adns_s_invaliddomain; + if (ctype_digit(p[0])) { + if (ctype_digit(p[1]) && ctype_digit(p[2])) { + c= (*p++ - '0')*100 + (*p++ - '0')*10 + (*p++ - '0'); + if (c >= 256) return adns_s_invaliddomain; + } else { + return adns_s_invaliddomain; + } + } else if (!(c= *p++)) { + return adns_s_invaliddomain; + } + } + if (!(flags & adns_qf_anyquote)) { + if (ctype_digit(c) || c == '-') { + if (!ll) return adns_s_invaliddomain; + } else if (!ctype_alpha(c)) { + return adns_s_invaliddomain; + } + } + if (ll == sizeof(label)) return adns_s_invaliddomain; + label[ll++]= c; + } + if (!ll) return adns_s_invaliddomain; + if (nlabs++ > 63) return adns_s_invaliddomain; + MKQUERY_ADDB(ll); + memcpy(rqp,label,ll); rqp+= ll; + } while (p!=pe); + + MKQUERY_ADDB(0); + MKQUERY_ADDW(typei->type & adns__rrt_typemask); /* QTYPE */ + MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */ + + vb->used= rqp - vb->buf; + assert(vb->used <= vb->avail); + + return adns_s_ok; +} + +void adns__query_tcp(adns_state ads, adns_query qu, struct timeval now) { + byte length[2]; + struct iovec iov[2]; + int wr, r; + + if (ads->tcpstate != server_ok) return; + + length[0]= (qu->query_dglen&0x0ff00U) >>8; + length[1]= (qu->query_dglen&0x0ff); + + if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->query_dglen+2)) return; + + timevaladd(&now,TCPMS); + qu->timeout= now; + qu->state= query_tcpsent; + LIST_LINK_TAIL(ads->timew,qu); + + if (ads->tcpsend.used) { + wr= 0; + } else { + iov[0].iov_base= length; + iov[0].iov_len= 2; + iov[1].iov_base= qu->query_dgram; + iov[1].iov_len= qu->query_dglen; + wr= writev(ads->tcpsocket,iov,2); + if (wr < 0) { + if (!(errno == EAGAIN || errno == EINTR || errno == ENOSPC || + errno == ENOBUFS || errno == ENOMEM)) { + adns__tcp_broken(ads,"write",strerror(errno)); + return; + } + wr= 0; + } + } + + if (wr<2) { + r= adns__vbuf_append(&ads->tcpsend,length,2-wr); assert(r); + wr= 0; + } else { + wr-= 2; + } + if (wrquery_dglen) { + r= adns__vbuf_append(&ads->tcpsend,qu->query_dgram+wr,qu->query_dglen-wr); assert(r); + } +} + +static void query_usetcp(adns_state ads, adns_query qu, struct timeval now) { + timevaladd(&now,TCPMS); + qu->timeout= now; + qu->state= query_tcpwait; + LIST_LINK_TAIL(ads->timew,qu); + adns__query_tcp(ads,qu,now); + adns__tcp_tryconnect(ads,now); +} + +void adns__query_udp(adns_state ads, adns_query qu, struct timeval now) { + struct sockaddr_in servaddr; + int serv, r; + + assert(qu->state == query_udp); + if ((qu->flags & adns_qf_usevc) || (qu->query_dglen > DNS_MAXUDP)) { + query_usetcp(ads,qu,now); + return; + } + + if (qu->udpretries >= UDPMAXRETRIES) { + adns__query_fail(ads,qu,adns_s_timeout); + return; + } + + serv= qu->udpnextserver; + memset(&servaddr,0,sizeof(servaddr)); + servaddr.sin_family= AF_INET; + servaddr.sin_addr= ads->servers[serv].addr; + servaddr.sin_port= htons(DNS_PORT); + + r= sendto(ads->udpsocket,qu->query_dgram,qu->query_dglen,0,&servaddr,sizeof(servaddr)); + if (r<0 && errno == EMSGSIZE) { query_usetcp(ads,qu,now); return; } + if (r<0) adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno)); + + timevaladd(&now,UDPRETRYMS); + qu->timeout= now; + qu->udpsent |= (1<udpnextserver= (serv+1)%ads->nservers; + qu->udpretries++; + LIST_LINK_TAIL(ads->timew,qu); +} diff --git a/src/types.c b/src/types.c index 38330cf..45741fa 100644 --- a/src/types.c +++ b/src/types.c @@ -1,4 +1,24 @@ -/**/ +/* + * types.c + * - RR-type-specific code, and the machinery to call it + */ +/* + * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include "internal.h" -- 2.30.2