support multiple DNS resolvers for queries (in DNSSTUB and GNS2DNS resolution for...
[oweals/gnunet.git] / src / gns / nss / nss_gns.c
index d97d51fb56016373581fc77d228f707959ffafa5..03ac6e09c14b9bea0a627535c8cddfe80f01306c 100644 (file)
@@ -15,7 +15,7 @@
 
     You should have received a copy of the GNU Lesser General Public License
     along with nss-mdns; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
     USA.
 ***/
 
 } while(0)
 
 
-/**
- * function to check if name ends with a specific suffix
- *
- * @param name the name to check
- * @param suffix the suffix to check for
- * @return 1 if true
- */
-static int ends_with(const char *name, const char* suffix) {
-    size_t ln, ls;
-    assert(name);
-    assert(suffix);
-
-    if ((ls = strlen(suffix)) > (ln = strlen(name)))
-        return 0;
-
-    return strcasecmp(name+ln-ls, suffix) == 0;
-}
-
-
-/**
- * Check if name is inside .gnu or .zkey TLD
- *
- * @param name name to check
- * @return 1 if true
- */
-static int verify_name_allowed (const char *name) {
-  return ends_with(name, ".gnu") || ends_with(name, ".zkey");
-}
-
 /**
  * The gethostbyname hook executed by nsswitch
  *
@@ -82,7 +53,8 @@ static int verify_name_allowed (const char *name) {
  * @param h_errnop idk
  * @return a nss_status code
  */
-enum nss_status _nss_gns_gethostbyname2_r(
+enum nss_status
+_nss_gns_gethostbyname2_r(
     const char *name,
     int af,
     struct hostent * result,
@@ -95,7 +67,6 @@ enum nss_status _nss_gns_gethostbyname2_r(
     enum nss_status status = NSS_STATUS_UNAVAIL;
     int i;
     size_t address_length, l, idx, astart;
-    int name_allowed;
 
     if (af == AF_UNSPEC)
 #ifdef NSS_IPV6_ONLY
@@ -133,28 +104,25 @@ enum nss_status _nss_gns_gethostbyname2_r(
     u.count = 0;
     u.data_len = 0;
 
-    name_allowed = verify_name_allowed(name);
-
-    if (name_allowed) {
-
-        if (!gns_resolve_name(af, name, &u) == 0)
-        {
-          status = NSS_STATUS_NOTFOUND;
-          goto finish;
-        }
-    }
-    else
-    {
-      status = NSS_STATUS_UNAVAIL;
-      goto finish;
-    }
-
-    if (u.count == 0) {
+    i = gns_resolve_name(af, name, &u);
+    if (-3 == i)
+      {
+        status = NSS_STATUS_NOTFOUND;
+        goto finish;
+      }
+    if (-2 == i)
+      {
+        status = NSS_STATUS_UNAVAIL;
+        goto finish;
+      }
+    if ( (-1 == i) ||
+         (u.count == 0) )
+      {
         *errnop = ETIMEDOUT;
         *h_errnop = HOST_NOT_FOUND;
         status = NSS_STATUS_NOTFOUND;
         goto finish;
-    }
+      }
 
 
     /* Alias names */
@@ -183,7 +151,8 @@ enum nss_status _nss_gns_gethostbyname2_r(
     /* Addresses */
     astart = idx;
     l = u.count*address_length;
-    memcpy(buffer+astart, &u.data, l);
+    if (0 != l)
+      memcpy(buffer+astart, &u.data, l);
     /* address_length is a multiple of 32bits, so idx is still aligned
      * correctly */
     idx += l;
@@ -211,7 +180,8 @@ finish:
  * @param h_errnop idk
  * @return a nss_status code
  */
-enum nss_status _nss_gns_gethostbyname_r (
+enum nss_status
+_nss_gns_gethostbyname_r (
     const char *name,
     struct hostent *result,
     char *buffer,
@@ -243,7 +213,8 @@ enum nss_status _nss_gns_gethostbyname_r (
  * @param h_errnop idk
  * @return NSS_STATUS_UNAVAIL
  */
-enum nss_status _nss_gns_gethostbyaddr_r(
+enum nss_status
+_nss_gns_gethostbyaddr_r(
     const void* addr,
     int len,
     int af,
@@ -252,104 +223,9 @@ enum nss_status _nss_gns_gethostbyaddr_r(
     size_t buflen,
     int *errnop,
     int *h_errnop) {
-  
-    struct userdata u;
-    enum nss_status status = NSS_STATUS_UNAVAIL;
-    int r;
-    size_t addr_len, idx, astart;
 
     *errnop = EINVAL;
     *h_errnop = NO_RECOVERY;
-
-    u.count = 0;
-    u.data_len = 0;
-
-    addr_len = af == AF_INET ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t);
-
-    if (len < (int) addr_len ||
-#ifdef NSS_IPV4_ONLY
-      af != AF_INET
-#elif NSS_IPV6_ONLY
-      af != AF_INET6
-#else
-      (af != AF_INET && af != AF_INET6)
-#endif
-      ) {
-      *errnop = EINVAL;
-      *h_errnop = NO_RECOVERY;
-
-      goto finish;
-    }
-
-    if (buflen < sizeof((char*) addr_len)) {
-      *errnop = ERANGE;
-      *h_errnop = NO_RECOVERY;
-      status = NSS_STATUS_TRYAGAIN;
-      goto finish;
-    }
-
-#if ! defined(NSS_IPV6_ONLY) && ! defined(NSS_IPV4_ONLY)
-    if (af == AF_INET)
-#endif
-#ifndef NSS_IPV6_ONLY
-    r = namecache_resolve_ip4((const ipv4_address_t*) addr, &u);
-#endif
-#if ! defined(NSS_IPV6_ONLY) && ! defined(NSS_IPV4_ONLY)
-    else
-#endif
-#ifndef NSS_IPV4_ONLY
-      r = namecache_resolve_ip6((const ipv6_address_t*) addr, &u);
-#endif
-    if (0 > r) {
-      *errnop = ETIMEDOUT;
-      *h_errnop = HOST_NOT_FOUND;
-      //NODE we allow to leak this into DNS so no NOTFOUND
-      status = NSS_STATUS_UNAVAIL;
-      goto finish;
-    }
-
-    *((char**) buffer) = NULL;
-    result->h_aliases = (char**) buffer;
-    idx = sizeof(char*);
-
-    assert(u.count > 0);
-    assert(u.data.name[0]);
-
-    if (buflen <
-        strlen(u.data.name[0])+1+ /* official names */
-        sizeof(char*)+ /* alias names */
-        addr_len+  /* address */
-        sizeof(void*)*2 + /* address list */
-        sizeof(void*)) {  /* padding to get the alignment right */
-      *errnop = ERANGE;
-      *h_errnop = NO_RECOVERY;
-      status = NSS_STATUS_TRYAGAIN;
-      goto finish;
-    }
-
-    /* Official name */
-    strcpy(buffer+idx, u.data.name[0]); 
-    result->h_name = buffer+idx;
-    idx += strlen(u.data.name[0])+1;
-    
-    result->h_addrtype = af;
-    result->h_length = addr_len;
-
-    /* Address */
-    astart = idx;
-    memcpy(buffer+astart, addr, addr_len);
-    idx += addr_len;
-
-    /* Address array, idx might not be at pointer alignment anymore, so we need
-     * to ensure it is*/
-    ALIGN(idx);
-
-    ((char**) (buffer+idx))[0] = buffer+astart;
-    ((char**) (buffer+idx))[1] = NULL;
-    result->h_addr_list = (char**) (buffer+idx);
-
-    status = NSS_STATUS_SUCCESS;
-finish:
-    return status;
+    //NOTE we allow to leak this into DNS so no NOTFOUND
+    return NSS_STATUS_UNAVAIL;
 }
-