summaryrefslogtreecommitdiff
path: root/src/adns-internal.h
blob: 2cdafbf9117bda31d5dc7b1e0d93d2d626dd543a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**/

#ifndef ADNS_INTERNAL_H_INCLUDED
#define ADNS_INTERNAL_H_INCLUDED

#include <sys/time.h>

#include "adns.h"

/* Configuration and constants */

#define MAXSERVERS 5
#define MAXUDPRETRIES 15
#define UDPRETRYMS 2000
#define TCPMS 30000
#define LOCALRESOURCEMS 20
#define UDPMAXDGRAM 512
#define NSPORT 53

/* Shared data structures */

union adns__align {
  adns_status status;
  char *cp;
  adns_rrtype type;
  int int;
  struct in_addr ia;
  unsigned long ul;
};

struct adns__query {
  /* FIXME: make sure this is all init'd properly */
  adns_query back, next;
  adns_query parent;
  struct { adns_query head, tail; } children;
  struct { adns_query back, next; } siblings;
  adns_rrtype type;
  adns_answer *answer;
  size_t ansalloc; ansused;
  int id, flags, udpretries; /* udpretries==-1 => _f_usevc or too big for UDP */
  int nextudpserver;
  unsigned long sentudp, senttcp; /* bitmaps indexed by server */
  struct timeval timeout;
  void *context;
  unsigned char *querymsg;
  int querylen;
  char owner[1];
  /* Possible states:
   *  Queue   child  id   answer    nextserver  sentudp             senttcp
   *  tosend  null   >=0  null      any         any                 any
   *  timew   null   >=0  null      any         at least 1 bit set  any
   *  childw  set    >=0  partial   any         any                 any
   *  output  null   -1   set/null  any         any                 any
   */
};

struct adns__vbuf {
  size_t used, avail;
  unsigned char *buf;
};

struct adns__state {
  /* FIXME: make sure this is all init'd properly */
  adns_initflags iflags;
  FILE *diagfile;
  struct { adns_query head, tail; } tosend, timew, childw, output;
  int nextid, udpsocket;
  adns_vbuf rqbuf, tcpsend, tcprecv;
  int nservers, tcpserver;
  enum adns__tcpstate { server_disc, server_connecting, server_ok } tcpstate;
  int tcpsocket;
  struct timeval tcptimeout;
  struct server {
    struct in_addr addr;
  } servers[MAXSERVERS];
};

/* From setup.c: */

void adns__vdiag(adns_state ads, adns_initflags prevent, const char *pfx,
		 int serv, const char *fmt, va_list al);
void adns__debug(adns_state ads, int serv, const char *fmt, ...) PRINTFFORMAT(2,3);
void adns__warn(adns_state ads, int serv, const char *fmt, ...) PRINTFFORMAT(2,3);
void adns__diag(adns_state ads, int serv, const char *fmt, ...) PRINTFFORMAT(2,3);

/* From submit.c: */

void adns__query_fail(adns_state ads, adns_query qu, adns_status stat);

/* From query.c: */

void adns__quproc_tosend(adns_state ads, adns_query qu, struct timeval now) {

/* Useful static inline functions: */

static inline void timevaladd(struct timeval *tv_io, long ms) {
  struct timeval tmp;
  assert(ms>=0);
  tmp= *tv_io;
  tmp.tv_usec += (ms%1000)*1000;
  tmp.tv_sec += ms/1000;
  if (tmp.tv_usec >= 1000) { tmp.tv_sec++; tmp.tv_usec -= 1000; }
  *tv_io= tmp;
}    

static inline int ctype_whitespace(int c) { return c==' ' || c=='\n' || c=='\t'; }
static inline int ctype_digit(int c) { return c>='0' && c<='9'; }

/* Useful macros */

#define LIST_UNLINK_PART(list,node,part) \
  do { \
    if ((node)->back) (node)->back->part next= (node)->part next; \
      else                        (list).head= (node)->part next; \
    if ((node)->next) (node)->next->part back= (node)->part back; \
      else                        (list).tail= (node)->part back; \
  } while(0)

#define LIST_LINK_TAIL_PART(list,node,part) \
  do { \
    (node)->part back= 0; \
    (node)->part next= (list).tail; \
    if ((list).tail) (list).tail->part back= (node); else (list).part head= (node); \
    (list).tail= (node); \
  } while(0)

#define LIST_UNLINK(list,node) LIST_UNLINK_PART(list,node,)
#define LIST_LINK_TAIL_PART(list,node) LIST_LINK_TAIL(list,node,)

#endif