]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
setup of state; delegation point setup.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 May 2007 09:34:01 +0000 (09:34 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 May 2007 09:34:01 +0000 (09:34 +0000)
git-svn-id: file:///svn/unbound/trunk@334 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iter_delegpt.c [new file with mode: 0644]
iterator/iter_delegpt.h [new file with mode: 0644]
iterator/iter_utils.c [new file with mode: 0644]
iterator/iter_utils.h [new file with mode: 0644]
iterator/iterator.c
iterator/iterator.h
util/net_help.c
util/net_help.h

index e1fa1339bad1d3fdb056312a82748c285c6803e8..e196dd365f89fe67da4c420b71e19b7372e67ae2 100644 (file)
@@ -1,6 +1,8 @@
 23 May 2007: Wouter
        - outside network does precise timers for roundtrip estimates for rtt
          and for setting timeout for UDP. Pending_udp takes milliseconds.
+       - cleaner iterator sockaddr conversion of forwarder address.
+       - iterator/iter_utils and iter_delegpt setup.
 
 22 May 2007: Wouter
        - outbound query list for modules and support to callback with the
diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c
new file mode 100644 (file)
index 0000000..5f2ef0e
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * iterator/iter_delegpt.c - delegation point with NS and address information.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file implements the Delegation Point. It contains a list of name servers
+ * and their addresses if known.
+ */
+#include "config.h"
+#include "iterator/iter_delegpt.h"
+#include "util/region-allocator.h"
+
+struct delegpt* 
+delegpt_create(struct region* region)
+{
+       struct delegpt* dp=(struct delegpt*)region_alloc(region, sizeof(*dp));
+       if(!dp)
+               return NULL;
+       memset(dp, 0, sizeof(*dp));
+       return dp;
+}
diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h
new file mode 100644 (file)
index 0000000..0e2ffed
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * iterator/iter_delegpt.h - delegation point with NS and address information.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file implements the Delegation Point. It contains a list of name servers
+ * and their addresses if known.
+ */
+
+#ifndef ITERATOR_ITER_DELEGPT_H
+#define ITERATOR_ITER_DELEGPT_H
+struct region;
+struct delegpt_ns;
+struct delegpt_addr;
+
+/**
+ * Delegation Point.
+ * For a domain name, the NS rrset, and the A and AAAA records for those.
+ */
+struct delegpt {
+       /** the domain name of the delegation point. */
+       uint8_t* name;
+       /** length of the delegation point name */
+       size_t namelen;
+       /** number of labels in delegation point */
+       int namelabs;
+
+       /** the nameservers, names from the NS RRset rdata. */
+       struct delegpt_ns* nslist;
+       /** the target addresses for delegation */
+       struct delegpt_addr* target_list;
+       /** the list of usable targets; subset of target_list */
+       struct delegpt_addr* usable_list;
+       /** the list of returned targets; subset of target_list */
+       struct delegpt_addr* result_list;
+};
+
+/**
+ * Nameservers for a delegation point.
+ */
+struct delegpt_ns {
+       /** next in list */
+       struct delegpt_ns* next;
+       /** name of nameserver */
+       uint8_t* name;
+       /** length of name */
+       size_t namelen;
+       /** 
+        * If the name has been resolved. false if not queried for yet.
+        * true if the address is known, or marked true if failed.
+        */
+       int resolved;
+};
+
+/**
+ * Address of target nameserver in delegation point.
+ */
+struct delegpt_addr {
+       /** next delegation point in results */
+       struct delegpt_addr* next_result;
+       /** next delegation point in usable list */
+       struct delegpt_addr* next_usable;
+       /** next delegation point in all targets list */
+       struct delegpt_addr* next_target;
+
+       /** delegation point address */
+       struct sockaddr_storage addr;
+       /** length of addr */
+       socklen_t addrlen;
+};
+
+/**
+ * Create new delegation point.
+ * @param region: where to allocate it.
+ * @return new delegation point or NULL on error.
+ */
+struct delegpt* delegpt_create(struct region* region);
+
+#endif /* ITERATOR_ITER_DELEGPT_H */
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
new file mode 100644 (file)
index 0000000..5af8317
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * iterator/iter_utils.c - iterative resolver module utility functions.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains functions to assist the iterator module.
+ * Configuration options. Forward zones. 
+ */
+#include "config.h"
+#include "iterator/iter_utils.h"
+#include "iterator/iterator.h"
+#include "util/net_help.h"
+#include "util/log.h"
+#include "util/config_file.h"
+
+int 
+iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
+{
+       int i;
+       /* target fetch policy */
+       iter_env->max_dependency_depth = 4;
+       iter_env->target_fetch_policy = (int*)calloc(
+               (size_t)iter_env->max_dependency_depth+1, sizeof(int));
+       if(iter_env->max_dependency_depth >= 1)
+               iter_env->target_fetch_policy[1] = 3;
+       if(iter_env->max_dependency_depth >= 2)
+               iter_env->target_fetch_policy[2] = 1;
+       /* TODO read setting from config */
+       if(!iter_env->target_fetch_policy)
+               return 0;
+       for(i=0; i<iter_env->max_dependency_depth+1; i++)
+               verbose(VERB_DETAIL, "target fetch policy for level %d is %d",
+                       i, iter_env->target_fetch_policy[i]);
+
+       /* forwarder address */
+       if(cfg->fwd_address && cfg->fwd_address[0]) {
+               if(!ipstrtoaddr(cfg->fwd_address, cfg->fwd_port,
+                       &iter_env->fwd_addr, &iter_env->fwd_addrlen)) {
+                       log_err("iterator: could not set forwarder address");
+                       return 0;
+               }
+               verbose(VERB_ALGO, "iterator: fwd queries to: %s %d",
+               cfg->fwd_address, cfg->fwd_port);
+       }
+       return 1;
+}
+
diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h
new file mode 100644 (file)
index 0000000..b3e6d77
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * iterator/iter_utils.h - iterative resolver module utility functions.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains functions to assist the iterator module.
+ * Configuration options. Forward zones. 
+ */
+
+#ifndef ITERATOR_ITER_UTILS_H
+#define ITERATOR_ITER_UTILS_H
+struct iter_env;
+struct config_file;
+
+/**
+ * Process config options and set iterator module state.
+ * Sets default values if no config is found.
+ * @param iter_env: iterator module state.
+ * @param cfg: config options.
+ * @return 0 on error.
+ */
+int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
+
+#endif /* ITERATOR_ITER_UTILS_H */
index 07c16e37b73f1648b1997e5e8682a75a4841d894..5867276f01a7f55d9cddf8dbefa529e1548d5fd6 100644 (file)
 #include "iterator/iterator.h"
 #include "util/module.h"
 #include "util/netevent.h"
-#include "util/config_file.h"
 #include "util/net_help.h"
 #include "util/storage/slabhash.h"
 #include "util/region-allocator.h"
 #include "services/cache/rrset.h"
-
-/** 
- * Set forwarder address 
- * @param ie: iterator global state.
- * @param ip: the server name.
- * @param port: port on server or NULL for default 53.
- * @return: false on error.
- */
-static int
-iter_set_fwd(struct iter_env* ie, const char* ip, int port)
-{
-        uint16_t p;
-        log_assert(ie && ip);
-        p = (uint16_t) port;
-        if(str_is_ip6(ip)) {
-                struct sockaddr_in6* sa =
-                        (struct sockaddr_in6*)&ie->fwd_addr;
-                ie->fwd_addrlen = (socklen_t)sizeof(struct sockaddr_in6);
-                memset(sa, 0, ie->fwd_addrlen);
-                sa->sin6_family = AF_INET6;
-                sa->sin6_port = (in_port_t)htons(p);
-                if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) {
-                        log_err("Bad ip6 address %s", ip);
-                        return 0;
-                }
-        } else { /* ip4 */
-                struct sockaddr_in* sa =
-                        (struct sockaddr_in*)&ie->fwd_addr;
-                ie->fwd_addrlen = (socklen_t)sizeof(struct sockaddr_in);
-                memset(sa, 0, ie->fwd_addrlen);
-                sa->sin_family = AF_INET;
-                sa->sin_port = (in_port_t)htons(p);
-                if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) {
-                        log_err("Bad ip4 address %s", ip);
-                        return 0;
-                }
-        }
-        verbose(VERB_ALGO, "iterator: fwd queries to: %s %d", ip, p);
-        return 1;
-}
+#include "iterator/iter_utils.h"
 
 /** iterator init */
 static int 
@@ -101,13 +61,9 @@ iter_init(struct module_env* env, int id)
                return 0;
        }
        env->modinfo[id] = (void*)iter_env;
-       /* set forwarder address */
-       if(env->cfg->fwd_address && env->cfg->fwd_address[0]) {
-               if(!iter_set_fwd(iter_env, env->cfg->fwd_address, 
-                       env->cfg->fwd_port)) {
-                       log_err("iterator: could not set forwarder address");
-                       return 0;
-               }
+       if(!iter_apply_cfg(iter_env, env->cfg)) {
+               log_err("iterator: could not apply configuration settings.");
+               return 0;
        }
        return 1;
 }
@@ -177,6 +133,7 @@ iter_new(struct module_qstate* qstate, int id)
        qstate->minfo[id] = iq;
        if(!iq) 
                return 0;
+       memset(iq, 0, sizeof(*iq));
        outbound_list_init(&iq->outlist);
        if(qstate->qinfo.has_cd)
                flags |= BIT_CD;
index 5a075e66345a02d9c9b46061638248d8711c5fba..981579beeb0358ebb8288c9e03e986806edbc7fb 100644 (file)
@@ -44,6 +44,7 @@
 #define ITERATOR_ITERATOR_H
 #include "services/outbound_list.h"
 struct module_func_block;
+struct delegpt;
 
 /**
  * Global state for the iterator. 
@@ -51,14 +52,138 @@ struct module_func_block;
 struct iter_env {
        /** address to forward to */
        struct sockaddr_storage fwd_addr;
-       /** length of fwd_addr */
+       /** length of fwd_addr, if not 0, forward mode is used */
        socklen_t fwd_addrlen;
+
+       /** 
+        * The hints -- these aren't stored in the cache because they don't 
+        * expire. The hints are always used to "prime" the cache. Note 
+        * that both root hints and stub zone "hints" are stored in this 
+        * data structure.
+        */
+       /* struct hints* hints TODO */
+
+       /** A flag to indicate whether or not we have an IPv6 route */
+       int supports_ipv6;
+
+       /** Mapping of forwarding zones to targets. */
+       /* struct fwds fwd_map TODO */
+
+       /** A set of inetaddrs that should never be queried. */
+       /* struct bla donotquery_addrs TODO */
+
+       /** The maximum dependency depth that this resolver will pursue. */
+       int max_dependency_depth;
+
+       /**
+        * The target fetch policy for each dependency level. This is 
+        * described as a simple number (per dependency level): 
+        *      negative numbers (usually just -1) mean fetch-all, 
+        *      0 means only fetch on demand, and 
+        *      positive numbers mean to fetch at most that many targets.
+        * array of max_dependency_depth+1 size.
+        */
+       int* target_fetch_policy;
+};
+
+/**
+ * State of the iterator for a query.
+ */
+enum iter_state {
+       /**
+        * Externally generated queries start at this state. Query restarts are
+        * reset to this state.
+        */
+       INIT_REQUEST_STATE = 0,
+
+       /**
+        * Root priming events reactivate here, most other events pass 
+        * through this naturally as the 2nd part of the INIT_REQUEST_STATE.
+        */
+       INIT_REQUEST_2_STATE,
+
+       /**
+        * Stub priming events reactivate here, most other events pass 
+        * through this naturally as the 3rd part of the INIT_REQUEST_STATE.
+        */
+       INIT_REQUEST_3_STATE,
+
+       /**
+        * Each time a delegation point changes for a given query or a 
+        * query times out and/or wakes up, this state is (re)visited. 
+        * This state is reponsible for iterating through a list of 
+        * nameserver targets.
+        */
+       QUERYTARGETS_STATE,
+
+       /**
+        * Responses to queries start at this state. This state handles 
+        * the decision tree associated with handling responses.
+        */
+       QUERY_RESP_STATE,
+
+       /** Responses to priming queries finish at this state. */
+       PRIME_RESP_STATE,
+
+       /** Responses to target queries start at this state. */
+       TARGET_RESP_STATE,
+
+       /** Responses that are to be returned upstream end at this state. */
+       FINISHED_STATE
 };
 
 /**
  * Per query state for the iterator module.
  */
 struct iter_qstate {
+       /** state of the iterator module 
+        * This is the state that event is in or should sent to -- all 
+        * requests should start with the INIT_REQUEST_STATE. All 
+        * responses should start with QUERY_RESP_STATE. Subsequent 
+        * processing of the event will change this state.
+        */
+       enum iter_state state;
+
+       /** final state for the iterator module 
+        * This is the state that responses should be routed to once the 
+        * response is final. For externally initiated queries, this 
+        * will be FINISHED_STATE, locally initiated queries will have 
+        * different final states.
+        */
+       enum iter_state final_state;
+
+       /** 
+        * This is a list of RRsets that must be prepended to the 
+        * ANSWER section of a response before being sent upstream.
+        */
+       /* TODO list of struct rrsets or something */
+
+       /** 
+        * This is the current delegation point for an in-progress query. This
+        * object retains state as to which delegation targets need to be
+        * (sub)queried for vs which ones have already been visited.
+        */
+       struct delegpt* dp;
+
+       /** number of outstanding target sub queries */
+       int num_target_queries;
+
+       /** outstanding direct queries */
+       int num_current_queries;
+
+       /** the number of times this query has been restarted. */
+       int query_restart_count;
+
+       /** the number of times this query as followed a referral. */
+       int referral_count;
+
+       /**
+        * This is flag that, if true, means that this event is 
+        * representing a stub priming query. It is meaningless unless 
+        * the finalState is the PRIMING_RESP_STATE.
+        */
+       int priming_stub;
+
        /** list of pending queries to authoritative servers. */
        struct outbound_list outlist;
 };
index 6041c0aaf79e0eb6b25e7654aa5f0539833bb10a..1cb52f0d0863c07f84a3ea86b550dc7dfc680aa4 100644 (file)
@@ -145,3 +145,34 @@ log_addr(struct sockaddr_storage* addr, socklen_t addrlen)
         verbose(VERB_DETAIL, "addr fam=%s port=%d dest=%s len=%d",
                 family, (int)port, dest, (int)addrlen);
 }
+
+int 
+ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
+       socklen_t* addrlen)
+{
+       uint16_t p;
+       if(!ip) return 0;
+       p = (uint16_t) port;
+       if(str_is_ip6(ip)) {
+               struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
+               *addrlen = (socklen_t)sizeof(struct sockaddr_in6);
+               memset(sa, 0, *addrlen);
+               sa->sin6_family = AF_INET6;
+               sa->sin6_port = (in_port_t)htons(p);
+               if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) {
+                       log_err("Bad ip6 address %s", ip);
+                       return 0;
+               }
+       } else { /* ip4 */
+               struct sockaddr_in* sa = (struct sockaddr_in*)addr;
+               *addrlen = (socklen_t)sizeof(struct sockaddr_in);
+               memset(sa, 0, *addrlen);
+               sa->sin_family = AF_INET;
+               sa->sin_port = (in_port_t)htons(p);
+               if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) {
+                       log_err("Bad ip4 address %s", ip);
+                       return 0;
+               }
+       }
+       return 1;
+}
index e123d8593f751ddca8dba9383ef6e8d13e5a472f..7b1c78f789edc2b80c98a0d49780d10cff3affde 100644 (file)
@@ -117,5 +117,15 @@ void* memdup(void* data, size_t len);
  */
 void log_addr(struct sockaddr_storage* addr, socklen_t addrlen);
 
+/**
+ * Convert ip address string and port to sockaddr.
+ * @param ip: ip4 or ip6 address string.
+ * @param port: port number, host format.
+ * @param addr: where to store sockaddr.
+ * @param addrlen: length of stored sockaddr is returned.
+ * @return 0 on error.
+ */
+int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
+       socklen_t* addrlen);
 
 #endif /* NET_HELP_H */