Back to index

opendkim  2.6.2
Classes | Defines | Functions | Variables
opendkim-dns.c File Reference
#include "build-config.h"
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#include <resolv.h>
#include <errno.h>
#include <dkim.h>
#include "opendkim-dns.h"
#include "opendkim-db.h"
#include "util.h"

Go to the source code of this file.

Classes

struct  dkimf_fquery

Defines

#define FALSE   0
#define TRUE   1
#define MIN(x, y)   ((x) < (y) ? (x) : (y))
#define BUFRSZ   1024
#define MAXPACKET   8192

Functions

static int dkimf_filedns_query (void *srv, int type, unsigned char *query, unsigned char *buf, size_t buflen, void **qh)
static int dkimf_filedns_cancel (void *srv, void *q)
static int dkimf_filedns_waitreply (void *srv, void *qh, struct timeval *to, size_t *bytes, int *error, int *dnssec)
int dkimf_filedns_setup (DKIM_LIB *lib, DKIMF_DB db)

Variables

static char opendkim_dns_c_id [] = "@(#)$Id: opendkim-dns.c,v 1.7.10.2 2010/10/28 04:28:04 cm-msk Exp $"

Class Documentation

struct dkimf_fquery

Definition at line 70 of file opendkim-dns.c.

Class Members
unsigned char fq_qbuf
size_t fq_qlen
unsigned char * fq_rbuf
size_t fq_rbuflen

Define Documentation

#define BUFRSZ   1024

Definition at line 66 of file opendkim-dns.c.

#define FALSE   0

Definition at line 57 of file opendkim-dns.c.

#define MAXPACKET   8192

Definition at line 67 of file opendkim-dns.c.

#define MIN (   x,
 
)    ((x) < (y) ? (x) : (y))

Definition at line 63 of file opendkim-dns.c.

#define TRUE   1

Definition at line 60 of file opendkim-dns.c.


Function Documentation

static int dkimf_filedns_cancel ( void *  srv,
void *  q 
) [static]

Definition at line 922 of file opendkim-dns.c.

{
       struct dkimf_fquery *fq;

       assert(srv != NULL);
       assert(q != NULL);

       fq = q;

       free(fq);

       return DKIM_DNS_SUCCESS;
}

Here is the caller graph for this function:

static int dkimf_filedns_query ( void *  srv,
int  type,
unsigned char *  query,
unsigned char *  buf,
size_t  buflen,
void **  qh 
) [static]

Definition at line 873 of file opendkim-dns.c.

{
       int status;
       struct dkimf_fquery *fq;
       size_t qlen;

       assert(srv != NULL);
       assert(query != NULL);
       assert(buf != NULL);
       assert(qh != NULL);

       if (type != T_TXT)
              return DKIM_DNS_SUCCESS;

       fq = malloc(sizeof *fq);
       if (fq == NULL)
              return DKIM_DNS_ERROR;
       fq->fq_rbuf = buf;
       fq->fq_rbuflen = buflen;

       qlen = res_mkquery(QUERY, query, C_IN, type, NULL, 0, NULL,
                          fq->fq_qbuf, sizeof fq->fq_qbuf);
       if (qlen == (size_t) -1)
       {
              free(fq);
              return DKIM_DNS_ERROR;
       }

       fq->fq_qlen = qlen;

       *qh = fq;

       return DKIM_DNS_SUCCESS;
}

Here is the caller graph for this function:

int dkimf_filedns_setup ( DKIM_LIB *  lib,
DKIMF_DB  db 
)

Definition at line 1122 of file opendkim-dns.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static int dkimf_filedns_waitreply ( void *  srv,
void *  qh,
struct timeval *  to,
size_t *  bytes,
int *  error,
int *  dnssec 
) [static]

Definition at line 953 of file opendkim-dns.c.

{
       _Bool exists = FALSE;
       int n;
       int status;
       int qdcount;
       char *cp;
       char *eom;
       char *qstart;
       struct dkimf_fquery *fq;
       char qname[BUFRSZ + 1];
       char buf[BUFRSZ + 1];
       HEADER hdr;
       struct dkimf_db_data dbd;

       assert(srv != NULL);
       assert(qh != NULL);

       fq = (struct dkimf_fquery *) qh;

       /* recover the query */
       qstart = fq->fq_rbuf;
       cp = fq->fq_qbuf;
       eom = cp + sizeof fq->fq_qbuf;
       memcpy(&hdr, cp, sizeof hdr);
       cp += HFIXEDSZ;

       /* skip over the name at the front of the answer */
       memset(qname, '\0', sizeof qname);
       for (qdcount = ntohs((unsigned short) hdr.qdcount);
            qdcount > 0;
            qdcount--)
       {
              /* copy it first */
              (void) dn_expand((unsigned char *) fq->fq_qbuf, eom, cp,
                               (char *) qname, sizeof qname);
 
              if ((n = dn_skipname(cp, eom)) < 0)
                     return DKIM_DNS_ERROR;;

              cp += n;

              /* extract the type and class */
              if (cp + INT16SZ + INT16SZ > eom)
                     return DKIM_DNS_ERROR;
;
              cp += (INT16SZ + INT16SZ);
       }

       /* search the DB */
       dbd.dbdata_buffer = buf;
       dbd.dbdata_buflen = sizeof buf;
       dbd.dbdata_flags = 0;

       memset(buf, '\0', sizeof buf);

       /* see if it's in the DB */
       status = dkimf_db_get((DKIMF_DB) srv, qname, strlen(qname), &dbd, 1,
                             &exists);
       if (status != 0)
              return DKIM_DNS_ERROR;

       /* prepare a reply header */
       hdr.qr = 1;

       if (!exists)
       {                    /* not found; set up an NXDOMAIN reply */
              hdr.rcode = NXDOMAIN;
              hdr.ancount = htons(0);

              memcpy(fq->fq_qbuf, &hdr, sizeof hdr);

              *bytes = fq->fq_qlen;
       }
       else
       {                    /* found, construct the reply */
              int elen;
              int slen;
              int olen;
              char *q;
              unsigned char *len;
              unsigned char *dnptrs[3];
              unsigned char **lastdnptr;
              HEADER newhdr;

              lastdnptr = &dnptrs[2];

              memset(&newhdr, '\0', sizeof newhdr);
              memset(&dnptrs, '\0', sizeof dnptrs);
              
              newhdr.qdcount = htons(1);
              newhdr.ancount = htons(1);
              newhdr.rcode = NOERROR;
              newhdr.opcode = hdr.opcode;
              newhdr.qr = 1;
              newhdr.id = hdr.id;

              dnptrs[0] = fq->fq_qbuf;

              /* copy out the new header */
              memcpy(fq->fq_rbuf, &newhdr, sizeof newhdr);

              cp = fq->fq_rbuf + HFIXEDSZ;
              eom = fq->fq_rbuf + fq->fq_rbuflen;

              /* question section */
              elen = dn_comp(qname, cp, eom - cp, dnptrs, lastdnptr);
              if (elen == -1)
                     return DKIM_DNS_ERROR;
              cp += elen;
              PUTSHORT(T_TXT, cp);
              PUTSHORT(C_IN, cp);

              /* answer section */
              elen = dn_comp(qname, cp, eom - cp, dnptrs, lastdnptr);
              if (elen == -1)
                     return DKIM_DNS_ERROR;
              cp += elen;
              PUTSHORT(T_TXT, cp);
              PUTSHORT(C_IN, cp);
              PUTLONG(0L, cp);

              len = cp;
              cp += INT16SZ;

              slen = dbd.dbdata_buflen;
              olen = 0;
              q = buf;

              while (slen > 0)
              {
                     elen = MIN(slen, 255);
                     *cp = (char) elen;
                     cp++;
                     olen++;
                     memcpy(cp, q, elen);
                     q += elen;
                     cp += elen;
                     olen += elen;
                     slen -= elen;
              }

              eom = cp;

              cp = len;
              PUTSHORT(olen, cp);

              *bytes = eom - qstart;
       }

       if (dnssec != NULL)
              *dnssec = DKIM_DNSSEC_UNKNOWN;

       return DKIM_DNS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char opendkim_dns_c_id[] = "@(#)$Id: opendkim-dns.c,v 1.7.10.2 2010/10/28 04:28:04 cm-msk Exp $" [static]

Definition at line 9 of file opendkim-dns.c.