chiark / gitweb /
Some more fiddlings.
[adns.git] / src / internal.h
1 /**/
2
3 #ifndef ADNS_INTERNAL_H_INCLUDED
4 #define ADNS_INTERNAL_H_INCLUDED
5
6 #include <sys/time.h>
7
8 #include "adns.h"
9
10 /* Configuration and constants */
11
12 #define MAXSERVERS 5
13 #define MAXUDPRETRIES 15
14 #define UDPRETRYMS 2000
15 #define TCPMS 30000
16 #define LOCALRESOURCEMS 20
17 #define UDPMAXDGRAM 512
18 #define NSPORT 53
19
20 /* Shared data structures */
21
22 union adns__align {
23   adns_status status;
24   char *cp;
25   adns_rrtype type;
26   int int;
27   struct in_addr ia;
28   unsigned long ul;
29 };
30
31 struct adns__query {
32   /* FIXME: make sure this is all init'd properly */
33   adns_query back, next;
34   adns_query parent;
35   struct { adns_query head, tail; } children;
36   struct { adns_query back, next; } siblings;
37   adns_rrtype type;
38   adns_answer *answer;
39   size_t ansalloc; ansused;
40   int id, flags, udpretries; /* udpretries==-1 => _f_usevc or too big for UDP */
41   int nextudpserver, senttcpserver;
42   unsigned long sentudp; /* bitmap indexed by server */
43   struct timeval timeout;
44   void *context;
45   unsigned char *querymsg;
46   int querylen;
47   char owner[1];
48   /* Possible states:
49    *  Queue   child  id   answer    nextserver  sentudp             senttcp
50    *  tosend  null   >=0  null      any         any                 any
51    *  timew   null   >=0  null      any         at least 1 bit set  any
52    *  childw  set    >=0  partial   any         any                 any
53    *  output  null   -1   set/null  any         any                 any
54    */
55 };
56
57 struct adns__vbuf {
58   size_t used, avail;
59   unsigned char *buf;
60 };
61
62 struct adns__state {
63   /* FIXME: make sure this is all init'd properly */
64   adns_initflags iflags;
65   FILE *diagfile;
66   struct { adns_query head, tail; } tosend, timew, childw, output;
67   int nextid, udpsocket;
68   adns_vbuf rqbuf, tcpsend, tcprecv;
69   int nservers, tcpserver;
70   enum adns__tcpstate { server_disconnected, server_connecting, server_ok } tcpstate;
71   int tcpsocket;
72   struct timeval tcptimeout;
73   struct server {
74     struct in_addr addr;
75   } servers[MAXSERVERS];
76 };
77
78 /* From setup.c: */
79
80 void adns__vdiag(adns_state ads, adns_initflags prevent, const char *pfx,
81                  int serv, const char *fmt, va_list al);
82 void adns__debug(adns_state ads, int serv, const char *fmt, ...) PRINTFFORMAT(3,4);
83 void adns__warn(adns_state ads, int serv, const char *fmt, ...) PRINTFFORMAT(3,4);
84 void adns__diag(adns_state ads, int serv, const char *fmt, ...) PRINTFFORMAT(3,4);
85
86 /* From submit.c: */
87
88 void adns__query_fail(adns_state ads, adns_query qu, adns_status stat);
89
90 /* From query.c: */
91
92 void adns__quproc_tosend(adns_state ads, adns_query qu, struct timeval now);
93
94 /* From event.c: */
95 void adns__tcp_broken(adns_state ads, const char *what, const char *why);
96 void adns__tcp_tryconnect(adns_state ads);
97
98 /* Useful static inline functions: */
99
100 static inline void timevaladd(struct timeval *tv_io, long ms) {
101   struct timeval tmp;
102   assert(ms>=0);
103   tmp= *tv_io;
104   tmp.tv_usec += (ms%1000)*1000;
105   tmp.tv_sec += ms/1000;
106   if (tmp.tv_usec >= 1000) { tmp.tv_sec++; tmp.tv_usec -= 1000; }
107   *tv_io= tmp;
108 }    
109
110 static inline int ctype_whitespace(int c) { return c==' ' || c=='\n' || c=='\t'; }
111 static inline int ctype_digit(int c) { return c>='0' && c<='9'; }
112
113 /* Useful macros */
114
115 #define LIST_UNLINK_PART(list,node,part) \
116   do { \
117     if ((node)->back) (node)->back->part next= (node)->part next; \
118       else                        (list).head= (node)->part next; \
119     if ((node)->next) (node)->next->part back= (node)->part back; \
120       else                        (list).tail= (node)->part back; \
121   } while(0)
122
123 #define LIST_LINK_TAIL_PART(list,node,part) \
124   do { \
125     (node)->part back= 0; \
126     (node)->part next= (list).tail; \
127     if ((list).tail) (list).tail->part back= (node); else (list).part head= (node); \
128     (list).tail= (node); \
129   } while(0)
130
131 #define LIST_UNLINK(list,node) LIST_UNLINK_PART(list,node,)
132 #define LIST_LINK_TAIL_PART(list,node) LIST_LINK_TAIL(list,node,)
133
134 #endif