Diff for /embedaddon/dnsmasq/src/dbus.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2021/03/17 00:56:46 version 1.1.1.5, 2023/09/27 11:02:07
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley/* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
   
    This program is free software; you can redistribute it and/or modify     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     it under the terms of the GNU General Public License as published by
Line 52  const char* introspection_xml_template = Line 52  const char* introspection_xml_template =
 "    <method name=\"SetFilterWin2KOption\">\n"  "    <method name=\"SetFilterWin2KOption\">\n"
 "      <arg name=\"filterwin2k\" direction=\"in\" type=\"b\"/>\n"  "      <arg name=\"filterwin2k\" direction=\"in\" type=\"b\"/>\n"
 "    </method>\n"  "    </method>\n"
   "    <method name=\"SetLocaliseQueriesOption\">\n"
   "      <arg name=\"localise-queries\" direction=\"in\" type=\"b\"/>\n"
   "    </method>\n"
 "    <method name=\"SetBogusPrivOption\">\n"  "    <method name=\"SetBogusPrivOption\">\n"
 "      <arg name=\"boguspriv\" direction=\"in\" type=\"b\"/>\n"  "      <arg name=\"boguspriv\" direction=\"in\" type=\"b\"/>\n"
 "    </method>\n"  "    </method>\n"
Line 88  const char* introspection_xml_template = Line 91  const char* introspection_xml_template =
 "    <method name=\"GetMetrics\">\n"  "    <method name=\"GetMetrics\">\n"
 "      <arg name=\"metrics\" direction=\"out\" type=\"a{su}\"/>\n"  "      <arg name=\"metrics\" direction=\"out\" type=\"a{su}\"/>\n"
 "    </method>\n"  "    </method>\n"
   "    <method name=\"GetServerMetrics\">\n"
   "      <arg name=\"metrics\" direction=\"out\" type=\"a{ss}\"/>\n"
   "    </method>\n"
   "    <method name=\"ClearMetrics\">\n"
   "    </method>\n"
 "  </interface>\n"  "  </interface>\n"
 "</node>\n";  "</node>\n";
   
Line 114  static dbus_bool_t add_watch(DBusWatch *watch, void *d Line 122  static dbus_bool_t add_watch(DBusWatch *watch, void *d
   w->next = daemon->watches;    w->next = daemon->watches;
   daemon->watches = w;    daemon->watches = w;
   
  w = data; /* no warning */  (void)data; /* no warning */
   return TRUE;    return TRUE;
 }  }
   
Line 134  static void remove_watch(DBusWatch *watch, void *data) Line 142  static void remove_watch(DBusWatch *watch, void *data)
         up = &(w->next);          up = &(w->next);
     }      }
   
  w = data; /* no warning */  (void)data; /* no warning */
 }  }
   
static void dbus_read_servers(DBusMessage *message)static DBusMessage* dbus_read_servers(DBusMessage *message)
 {  {
   DBusMessageIter iter;    DBusMessageIter iter;
   union  mysockaddr addr, source_addr;    union  mysockaddr addr, source_addr;
   char *domain;    char *domain;
       
  dbus_message_iter_init(message, &iter);  if (!dbus_message_iter_init(message, &iter))
     {
       return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
                                     "Failed to initialize dbus message iter");
     }
   
   mark_servers(SERV_FROM_DBUS);    mark_servers(SERV_FROM_DBUS);
       
Line 215  static void dbus_read_servers(DBusMessage *message) Line 227  static void dbus_read_servers(DBusMessage *message)
           domain = NULL;            domain = NULL;
                   
         if (!skip)          if (!skip)
          add_update_server(SERV_FROM_DBUS, &addr, &source_addr, NULL, domain);          add_update_server(SERV_FROM_DBUS, &addr, &source_addr, NULL, domain, NULL);
             
       } while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING);         } while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING); 
     }      }
         
   /* unlink and free anything still marked. */    /* unlink and free anything still marked. */
   cleanup_servers();    cleanup_servers();
     return NULL;
 }  }
   
 #ifdef HAVE_LOOP  #ifdef HAVE_LOOP
Line 276  static DBusMessage* dbus_read_servers_ex(DBusMessage * Line 289  static DBusMessage* dbus_read_servers_ex(DBusMessage *
     {      {
       const char *str = NULL;        const char *str = NULL;
       union  mysockaddr addr, source_addr;        union  mysockaddr addr, source_addr;
      int flags = 0;      u16 flags = 0;
       char interface[IF_NAMESIZE];        char interface[IF_NAMESIZE];
       char *str_addr, *str_domain = NULL;        char *str_addr, *str_domain = NULL;
         struct server_details sdetails = { 0 };
         sdetails.addr = &addr;
         sdetails.source_addr = &source_addr;
         sdetails.interface = interface;
         sdetails.flags = &flags;
   
       if (strings)        if (strings)
         {          {
Line 361  static DBusMessage* dbus_read_servers_ex(DBusMessage * Line 379  static DBusMessage* dbus_read_servers_ex(DBusMessage *
           strcpy(str_addr, str);            strcpy(str_addr, str);
         }          }
   
       memset(&addr, 0, sizeof(addr));  
       memset(&source_addr, 0, sizeof(source_addr));  
       memset(&interface, 0, sizeof(interface));  
   
       /* parse the IP address */  
       if ((addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, &flags)))  
         {  
           error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,  
                                                 "Invalid IP address '%s': %s",  
                                                 str, addr_err);  
           break;  
         }  
         
       /* 0.0.0.0 for server address == NULL, for Dbus */  
       if (addr.in.sin_family == AF_INET &&  
           addr.in.sin_addr.s_addr == 0)  
         flags |= SERV_NO_ADDR;  
         
       if (strings)        if (strings)
         {          {
           char *p;            char *p;
Line 392  static DBusMessage* dbus_read_servers_ex(DBusMessage * Line 392  static DBusMessage* dbus_read_servers_ex(DBusMessage *
             else               else 
               p = NULL;                p = NULL;
                           
            add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain);             if (strings && strlen(str_addr) == 0)
                add_update_server(SERV_LITERAL_ADDRESS | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain, NULL);
              else
                {
                  if ((addr_err = parse_server(str_addr, &sdetails)))
                    {
                      error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
                                                            "Invalid IP address '%s': %s",
                                                            str, addr_err);
                      break;
                    }
                  
                  while (parse_server_next(&sdetails))
                    {
                      if ((addr_err = parse_server_addr(&sdetails)))
                        {
                          error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
                                                                "Invalid IP address '%s': %s",
                                                                str, addr_err);
                          break;
                        }
                      
                      add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain, NULL);
                    }
                }
           } while ((str_domain = p));            } while ((str_domain = p));
         }          }
       else        else
Line 406  static DBusMessage* dbus_read_servers_ex(DBusMessage * Line 430  static DBusMessage* dbus_read_servers_ex(DBusMessage *
             if (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING)              if (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING)
               dbus_message_iter_get_basic(&string_iter, &str);                dbus_message_iter_get_basic(&string_iter, &str);
             dbus_message_iter_next (&string_iter);              dbus_message_iter_next (&string_iter);
   
               if ((addr_err = parse_server(str_addr, &sdetails)))
                 {
                   error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
                                                         "Invalid IP address '%s': %s",
                                                         str, addr_err);
                   break;
                 }
                           
            add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str);            while (parse_server_next(&sdetails))
               {
                 if ((addr_err = parse_server_addr(&sdetails)))
                   {
                     error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
                                                           "Invalid IP address '%s': %s",
                                                           str, addr_err);
                     break;
                   }
                 
                 /* 0.0.0.0 for server address == NULL, for Dbus */
                 if (addr.in.sin_family == AF_INET &&
                     addr.in.sin_addr.s_addr == 0)
                   flags |= SERV_LITERAL_ADDRESS;
                 else
                   flags &= ~SERV_LITERAL_ADDRESS;
                 
                 add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str, NULL);
               }
           } while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);            } while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
         }          }
               
       if (sdetails.orig_hostinfo)
         freeaddrinfo(sdetails.orig_hostinfo);
       
       /* jump to next element in outer array */        /* jump to next element in outer array */
       dbus_message_iter_next(&array_iter);        dbus_message_iter_next(&array_iter);
     }      }
   
   cleanup_servers();    cleanup_servers();
    
   if (dup)    if (dup)
     free(dup);      free(dup);
   
Line 549  static DBusMessage *dbus_add_lease(DBusMessage* messag Line 602  static DBusMessage *dbus_add_lease(DBusMessage* messag
                                          "Invalid IP address '%s'", ipaddr);                                           "Invalid IP address '%s'", ipaddr);
         
   hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);    hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
     if (hw_len < 0)
       return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
                                            "Invalid HW address '%s'", hwaddr);
   
   if (hw_type == 0 && hw_len != 0)    if (hw_type == 0 && hw_len != 0)
     hw_type = ARPHRD_ETHER;      hw_type = ARPHRD_ETHER;
       
Line 636  static DBusMessage *dbus_get_metrics(DBusMessage* mess Line 693  static DBusMessage *dbus_get_metrics(DBusMessage* mess
   return reply;    return reply;
 }  }
   
   static void add_dict_entry(DBusMessageIter *container, const char *key, const char *val)
   {
     DBusMessageIter dict;
   
     dbus_message_iter_open_container(container, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
     dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &key);
     dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &val);
     dbus_message_iter_close_container(container, &dict);
   }
   
   static void add_dict_int(DBusMessageIter *container, const char *key, const unsigned int val)
   {
     snprintf(daemon->namebuff, MAXDNAME, "%u", val);
     
     add_dict_entry(container, key, daemon->namebuff);
   }
   
   static DBusMessage *dbus_get_server_metrics(DBusMessage* message)
   {
     DBusMessage *reply = dbus_message_new_method_return(message);
     DBusMessageIter server_array, dict_array, server_iter;
     struct server *serv;
     
     dbus_message_iter_init_append(reply, &server_iter);
     dbus_message_iter_open_container(&server_iter, DBUS_TYPE_ARRAY, "a{ss}", &server_array);
   
     /* sum counts from different records for same server */
     for (serv = daemon->servers; serv; serv = serv->next)
       serv->flags &= ~SERV_MARK;
     
     for (serv = daemon->servers; serv; serv = serv->next)
       if (!(serv->flags & SERV_MARK))
         {
           unsigned int port;
           unsigned int queries = 0, failed_queries = 0, nxdomain_replies = 0, retrys = 0;
           unsigned int sigma_latency = 0, count_latency = 0;
           
           struct server *serv1;
   
           for (serv1 = serv; serv1; serv1 = serv1->next)
             if (!(serv1->flags & SERV_MARK) && sockaddr_isequal(&serv->addr, &serv1->addr))
               {
                 serv1->flags |= SERV_MARK;
                 queries += serv1->queries;
                 failed_queries += serv1->failed_queries;
                 nxdomain_replies += serv1->nxdomain_replies;
                 retrys += serv1->retrys;
                 sigma_latency += serv1->query_latency;
                 count_latency++;
               }
           
           dbus_message_iter_open_container(&server_array, DBUS_TYPE_ARRAY, "{ss}", &dict_array);
           
           port = prettyprint_addr(&serv->addr, daemon->namebuff);
           add_dict_entry(&dict_array, "address", daemon->namebuff);
           
           add_dict_int(&dict_array, "port", port);
           add_dict_int(&dict_array, "queries", serv->queries);
           add_dict_int(&dict_array, "failed_queries", serv->failed_queries);
           add_dict_int(&dict_array, "nxdomain", serv->nxdomain_replies);
           add_dict_int(&dict_array, "retries", serv->retrys);
           add_dict_int(&dict_array, "latency", sigma_latency/count_latency);
           
           dbus_message_iter_close_container(&server_array, &dict_array);
         }
     
     dbus_message_iter_close_container(&server_iter, &server_array);
     
     return reply;
   }
   
 DBusHandlerResult message_handler(DBusConnection *connection,   DBusHandlerResult message_handler(DBusConnection *connection, 
                                   DBusMessage *message,                                     DBusMessage *message, 
                                   void *user_data)                                    void *user_data)
Line 672  DBusHandlerResult message_handler(DBusConnection *conn Line 800  DBusHandlerResult message_handler(DBusConnection *conn
 #endif  #endif
   else if (strcmp(method, "SetServers") == 0)    else if (strcmp(method, "SetServers") == 0)
     {      {
      dbus_read_servers(message);      reply = dbus_read_servers(message);
       new_servers = 1;        new_servers = 1;
     }      }
   else if (strcmp(method, "SetServersEx") == 0)    else if (strcmp(method, "SetServersEx") == 0)
Line 689  DBusHandlerResult message_handler(DBusConnection *conn Line 817  DBusHandlerResult message_handler(DBusConnection *conn
     {      {
       reply = dbus_set_bool(message, OPT_FILTER, "filterwin2k");        reply = dbus_set_bool(message, OPT_FILTER, "filterwin2k");
     }      }
     else if (strcmp(method, "SetLocaliseQueriesOption") == 0)
       {
         reply = dbus_set_bool(message, OPT_LOCALISE, "localise-queries");
       }
   else if (strcmp(method, "SetBogusPrivOption") == 0)    else if (strcmp(method, "SetBogusPrivOption") == 0)
     {      {
       reply = dbus_set_bool(message, OPT_BOGUSPRIV, "bogus-priv");        reply = dbus_set_bool(message, OPT_BOGUSPRIV, "bogus-priv");
Line 707  DBusHandlerResult message_handler(DBusConnection *conn Line 839  DBusHandlerResult message_handler(DBusConnection *conn
     {      {
       reply = dbus_get_metrics(message);        reply = dbus_get_metrics(message);
     }      }
     else if (strcmp(method, "GetServerMetrics") == 0)
       {
         reply = dbus_get_server_metrics(message);
       }
     else if (strcmp(method, "ClearMetrics") == 0)
       {
         clear_metrics();
       }
   else if (strcmp(method, "ClearCache") == 0)    else if (strcmp(method, "ClearCache") == 0)
     clear_cache = 1;      clear_cache = 1;
   else    else
Line 715  DBusHandlerResult message_handler(DBusConnection *conn Line 855  DBusHandlerResult message_handler(DBusConnection *conn
   if (new_servers)    if (new_servers)
     {      {
       my_syslog(LOG_INFO, _("setting upstream servers from DBus"));        my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
      check_servers();      check_servers(0);
       if (option_bool(OPT_RELOAD))        if (option_bool(OPT_RELOAD))
         clear_cache = 1;          clear_cache = 1;
     }      }
Line 723  DBusHandlerResult message_handler(DBusConnection *conn Line 863  DBusHandlerResult message_handler(DBusConnection *conn
   if (clear_cache)    if (clear_cache)
     clear_cache_and_reload(dnsmasq_time());      clear_cache_and_reload(dnsmasq_time());
       
  method = user_data; /* no warning */  (void)user_data; /* no warning */
   
   /* If no reply or no error, return nothing */    /* If no reply or no error, return nothing */
   if (!reply)    if (!reply)
Line 749  char *dbus_init(void) Line 889  char *dbus_init(void)
   
   dbus_error_init (&dbus_error);    dbus_error_init (&dbus_error);
   if (!(connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error)))    if (!(connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error)))
    return NULL;    {
          dbus_error_free(&dbus_error);
       return NULL;
     }
   
   dbus_connection_set_exit_on_disconnect(connection, FALSE);    dbus_connection_set_exit_on_disconnect(connection, FALSE);
   dbus_connection_set_watch_functions(connection, add_watch, remove_watch,     dbus_connection_set_watch_functions(connection, add_watch, remove_watch, 
                                       NULL, NULL, NULL);                                        NULL, NULL, NULL);

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>