[CIFS] Adds to dns_resolver checking if the server name is an IP addr and skipping...
authorSteve French <sfrench@us.ibm.com>
Sat, 26 Apr 2008 00:22:23 +0000 (00:22 +0000)
committerSteve French <sfrench@us.ibm.com>
Sat, 26 Apr 2008 00:22:23 +0000 (00:22 +0000)
Signed-off-by: Igor Mammedov <niallain@gmail.com>
Signed-off-by: sfrench@us.ibm.com
fs/cifs/dns_resolve.c

index 7cc86c4..939e256 100644 (file)
@@ -55,6 +55,32 @@ struct key_type key_type_dns_resolver = {
        .match       = user_match,
 };
 
+/* Checks if supplied name is IP address
+ * returns:
+ *             1 - name is IP
+ *             0 - name is not IP
+ */
+static int is_ip(const char *name)
+{
+       int rc;
+       struct sockaddr_in sin_server;
+       struct sockaddr_in6 sin_server6;
+
+       rc = cifs_inet_pton(AF_INET, name,
+                       &sin_server.sin_addr.s_addr);
+
+       if (rc <= 0) {
+               /* not ipv4 address, try ipv6 */
+               rc = cifs_inet_pton(AF_INET6, name,
+                               &sin_server6.sin6_addr.in6_u);
+               if (rc > 0)
+                       return 1;
+       } else {
+               return 1;
+       }
+       /* we failed translating address */
+       return 0;
+}
 
 /* Resolves server name to ip address.
  * input:
@@ -67,8 +93,9 @@ int
 dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
 {
        int rc = -EAGAIN;
-       struct key *rkey;
+       struct key *rkey = ERR_PTR(-EAGAIN);
        char *name;
+       char *data = NULL;
        int len;
 
        if (!ip_addr || !unc)
@@ -97,26 +124,41 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        memcpy(name, unc+2, len);
        name[len] = 0;
 
+       if (is_ip(name)) {
+               cFYI(1, ("%s: it is IP, skipping dns upcall: %s",
+                                       __func__, name));
+               data = name;
+               goto skip_upcall;
+       }
+
        rkey = request_key(&key_type_dns_resolver, name, "");
        if (!IS_ERR(rkey)) {
-               len = strlen(rkey->payload.data);
-               *ip_addr = kmalloc(len+1, GFP_KERNEL);
-               if (*ip_addr) {
-                       memcpy(*ip_addr, rkey->payload.data, len);
-                       (*ip_addr)[len] = '\0';
-                       cFYI(1, ("%s: resolved: %s to %s", __func__,
+               data = rkey->payload.data;
+               cFYI(1, ("%s: resolved: %s to %s", __func__,
                                        rkey->description,
                                        *ip_addr
                                ));
+       } else {
+               cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+               goto out;
+       }
+
+skip_upcall:
+       if (data) {
+               len = strlen(data);
+               *ip_addr = kmalloc(len+1, GFP_KERNEL);
+               if (*ip_addr) {
+                       memcpy(*ip_addr, data, len);
+                       (*ip_addr)[len] = '\0';
                        rc = 0;
                } else {
                        rc = -ENOMEM;
                }
-               key_put(rkey);
-       } else {
-               cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+               if (!IS_ERR(rkey))
+                       key_put(rkey);
        }
 
+out:
        kfree(name);
        return rc;
 }