"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/bin/named/notify.c" (7 Sep 2020, 4408 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "notify.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 /* $Id: notify.c,v 1.37 2007/06/19 23:46:59 tbox Exp $ */
   13 
   14 #include <config.h>
   15 
   16 #include <isc/log.h>
   17 #include <isc/print.h>
   18 
   19 #include <dns/message.h>
   20 #include <dns/rdataset.h>
   21 #include <dns/result.h>
   22 #include <dns/tsig.h>
   23 #include <dns/view.h>
   24 #include <dns/zone.h>
   25 #include <dns/zt.h>
   26 
   27 #include <named/log.h>
   28 #include <named/notify.h>
   29 
   30 /*! \file
   31  * \brief
   32  * This module implements notify as in RFC1996.
   33  */
   34 
   35 static void
   36 notify_log(ns_client_t *client, int level, const char *fmt, ...) {
   37     va_list ap;
   38 
   39     va_start(ap, fmt);
   40     ns_client_logv(client, DNS_LOGCATEGORY_NOTIFY, NS_LOGMODULE_NOTIFY,
   41                level, fmt, ap);
   42     va_end(ap);
   43 }
   44 
   45 static void
   46 respond(ns_client_t *client, isc_result_t result) {
   47     dns_rcode_t rcode;
   48     dns_message_t *message;
   49     isc_result_t msg_result;
   50 
   51     message = client->message;
   52     rcode = dns_result_torcode(result);
   53 
   54     msg_result = dns_message_reply(message, true);
   55     if (msg_result != ISC_R_SUCCESS)
   56         msg_result = dns_message_reply(message, false);
   57     if (msg_result != ISC_R_SUCCESS) {
   58         ns_client_next(client, msg_result);
   59         return;
   60     }
   61     message->rcode = rcode;
   62     if (rcode == dns_rcode_noerror)
   63         message->flags |= DNS_MESSAGEFLAG_AA;
   64     else
   65         message->flags &= ~DNS_MESSAGEFLAG_AA;
   66     ns_client_send(client);
   67 }
   68 
   69 void
   70 ns_notify_start(ns_client_t *client) {
   71     dns_message_t *request = client->message;
   72     isc_result_t result;
   73     dns_name_t *zonename;
   74     dns_rdataset_t *zone_rdataset;
   75     dns_zone_t *zone = NULL;
   76     char namebuf[DNS_NAME_FORMATSIZE];
   77     char tsigbuf[DNS_NAME_FORMATSIZE * 2 + sizeof(": TSIG '' ()")];
   78     dns_tsigkey_t *tsigkey;
   79 
   80     /*
   81      * Interpret the question section.
   82      */
   83     result = dns_message_firstname(request, DNS_SECTION_QUESTION);
   84     if (result != ISC_R_SUCCESS) {
   85         notify_log(client, ISC_LOG_NOTICE,
   86                "notify question section empty");
   87         result = DNS_R_FORMERR;
   88         goto done;
   89     }
   90 
   91     /*
   92      * The question section must contain exactly one question.
   93      */
   94     zonename = NULL;
   95     dns_message_currentname(request, DNS_SECTION_QUESTION, &zonename);
   96     zone_rdataset = ISC_LIST_HEAD(zonename->list);
   97     if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) {
   98         notify_log(client, ISC_LOG_NOTICE,
   99                "notify question section contains multiple RRs");
  100         result = DNS_R_FORMERR;
  101         goto done;
  102     }
  103 
  104     /* The zone section must have exactly one name. */
  105     result = dns_message_nextname(request, DNS_SECTION_ZONE);
  106     if (result != ISC_R_NOMORE) {
  107         notify_log(client, ISC_LOG_NOTICE,
  108                "notify question section contains multiple RRs");
  109         result = DNS_R_FORMERR;
  110         goto done;
  111     }
  112 
  113     /* The one rdataset must be an SOA. */
  114     if (zone_rdataset->type != dns_rdatatype_soa) {
  115         notify_log(client, ISC_LOG_NOTICE,
  116                "notify question section contains no SOA");
  117         result = DNS_R_FORMERR;
  118         goto done;
  119     }
  120 
  121     tsigkey = dns_message_gettsigkey(request);
  122     if (tsigkey != NULL) {
  123         dns_name_format(&tsigkey->name, namebuf, sizeof(namebuf));
  124 
  125         if (tsigkey->generated) {
  126             char cnamebuf[DNS_NAME_FORMATSIZE];
  127             dns_name_format(tsigkey->creator, cnamebuf,
  128                     sizeof(cnamebuf));
  129             snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s' (%s)",
  130                  namebuf, cnamebuf);
  131         } else {
  132             snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s'",
  133                  namebuf);
  134         }
  135     } else
  136         tsigbuf[0] = '\0';
  137 
  138     dns_name_format(zonename, namebuf, sizeof(namebuf));
  139     result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, &zone);
  140     if (result == ISC_R_SUCCESS) {
  141         dns_zonetype_t zonetype = dns_zone_gettype(zone);
  142 
  143         if ((zonetype == dns_zone_master) ||
  144             (zonetype == dns_zone_slave) ||
  145             (zonetype == dns_zone_stub))
  146         {
  147             isc_sockaddr_t *from = ns_client_getsockaddr(client);
  148             isc_sockaddr_t *to = ns_client_getdestaddr(client);
  149             notify_log(client, ISC_LOG_INFO,
  150                    "received notify for zone '%s'%s",
  151                    namebuf, tsigbuf);
  152             result = dns_zone_notifyreceive2(zone, from, to,
  153                              request);
  154             goto done;
  155         }
  156     }
  157 
  158     notify_log(client, ISC_LOG_NOTICE,
  159            "received notify for zone '%s'%s: not authoritative",
  160            namebuf, tsigbuf);
  161     result = DNS_R_NOTAUTH;
  162 
  163  done:
  164     if (zone != NULL)
  165         dns_zone_detach(&zone);
  166     respond(client, result);
  167 }