Commit 6d740164 authored by Paulo Alcantara's avatar Paulo Alcantara Committed by Steve French
Browse files

cifs: set resolved ip in sockaddr



All callers from dns_resolve_server_name_to_ip() used to convert the
ip addr string back to sockaddr, so do that inside
dns_resolve_server_name_to_ip() and avoid duplicating code.

Signed-off-by: default avatarPaulo Alcantara (SUSE) <pc@cjr.nz>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 2301bc10
Loading
Loading
Loading
Loading
+12 −16
Original line number Diff line number Diff line
@@ -91,7 +91,8 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
{
	int rc;
	int len;
	char *unc, *ipaddr = NULL;
	char *unc;
	struct sockaddr_storage ss;
	time64_t expiry, now;
	unsigned long ttl = SMB_DNS_RESOLVE_INTERVAL_DEFAULT;

@@ -111,7 +112,11 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
	}
	scnprintf(unc, len, "\\\\%s", server->hostname);

	rc = dns_resolve_server_name_to_ip(unc, &ipaddr, &expiry);
	spin_lock(&server->srv_lock);
	ss = server->dstaddr;
	spin_unlock(&server->srv_lock);

	rc = dns_resolve_server_name_to_ip(unc, (struct sockaddr *)&ss, &expiry);
	kfree(unc);

	if (rc < 0) {
@@ -121,22 +126,13 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
	}

	spin_lock(&server->srv_lock);
	rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr,
				  strlen(ipaddr));
	memcpy(&server->dstaddr, &ss, sizeof(server->dstaddr));
	spin_unlock(&server->srv_lock);
	kfree(ipaddr);

	/* rc == 1 means success here */
	if (rc) {
	now = ktime_get_real_seconds();
	if (expiry && expiry > now)
			/*
			 * To make sure we don't use the cached entry, retry 1s
			 * after expiry.
			 */
		/* To make sure we don't use the cached entry, retry 1s */
		ttl = max_t(unsigned long, expiry - now, SMB_DNS_RESOLVE_INTERVAL_MIN) + 1;
	}
	rc = !rc ? -1 : 0;

requeue_resolve:
	cifs_dbg(FYI, "%s: next dns resolution scheduled for %lu seconds in the future\n",
+1 −23
Original line number Diff line number Diff line
@@ -9,28 +9,6 @@
#include "fs_context.h"
#include "dfs.h"

/* Resolve UNC server name and set destination ip address in fs context */
static int resolve_unc(const char *path, struct smb3_fs_context *ctx)
{
	int rc;
	char *ip = NULL;

	rc = dns_resolve_server_name_to_ip(path, &ip, NULL);
	if (rc < 0) {
		cifs_dbg(FYI, "%s: failed to resolve UNC server name: %d\n", __func__, rc);
		return rc;
	}

	if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip, strlen(ip))) {
		cifs_dbg(VFS, "%s: could not determinate destination address\n", __func__);
		rc = -EHOSTUNREACH;
	} else
		rc = 0;

	kfree(ip);
	return rc;
}

/**
 * dfs_parse_target_referral - set fs context for dfs target referral
 *
@@ -68,7 +46,7 @@ int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_para
	if (rc)
		goto out;

	rc = resolve_unc(path, ctx);
	rc = dns_resolve_server_name_to_ip(path, (struct sockaddr *)&ctx->dstaddr, NULL);

out:
	kfree(path);
+5 −12
Original line number Diff line number Diff line
@@ -1314,8 +1314,7 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
	char unc[sizeof("\\\\") + SERVER_NAME_LENGTH] = {0};
	const char *host;
	size_t hostlen;
	char *ip = NULL;
	struct sockaddr sa;
	struct sockaddr_storage ss;
	bool match;
	int rc;

@@ -1330,23 +1329,17 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
	extract_unc_hostname(s1, &host, &hostlen);
	scnprintf(unc, sizeof(unc), "\\\\%.*s", (int)hostlen, host);

	rc = dns_resolve_server_name_to_ip(unc, &ip, NULL);
	rc = dns_resolve_server_name_to_ip(unc, (struct sockaddr *)&ss, NULL);
	if (rc < 0) {
		cifs_dbg(FYI, "%s: could not resolve %.*s. assuming server address matches.\n",
			 __func__, (int)hostlen, host);
		return true;
	}

	if (!cifs_convert_address(&sa, ip, strlen(ip))) {
		cifs_dbg(VFS, "%s: failed to convert address \'%s\'. skip address matching.\n",
			 __func__, ip);
	} else {
	cifs_server_lock(server);
		match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, &sa);
	match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss);
	cifs_server_unlock(server);
	}

	kfree(ip);
	return match;
}

+24 −25
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
 *
 */

#include <linux/inet.h>
#include <linux/slab.h>
#include <linux/dns_resolver.h>
#include "dns_resolve.h"
@@ -25,17 +26,13 @@
 * @ip_addr: Where to return the IP address.
 * @expiry: Where to return the expiry time for the dns record.
 *
 * The IP address will be returned in string form, and the caller is
 * responsible for freeing it.
 *
 * Returns length of result on success, -ve on error.
 * Returns zero success, -ve on error.
 */
int
dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry)
dns_resolve_server_name_to_ip(const char *unc, struct sockaddr *ip_addr, time64_t *expiry)
{
	struct sockaddr_storage ss;
	const char *hostname, *sep;
	char *name;
	char *ip;
	int len, rc;

	if (!ip_addr || !unc)
@@ -60,30 +57,32 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry)
			 __func__, unc);

	/* Try to interpret hostname as an IPv4 or IPv6 address */
	rc = cifs_convert_address((struct sockaddr *)&ss, hostname, len);
	if (rc > 0)
		goto name_is_IP_address;
	rc = cifs_convert_address(ip_addr, hostname, len);
	if (rc > 0) {
		cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %*.*s\n", __func__, len, len,
			 hostname);
		return 0;
	}

	/* Perform the upcall */
	rc = dns_query(current->nsproxy->net_ns, NULL, hostname, len,
		       NULL, ip_addr, expiry, false);
	if (rc < 0)
		       NULL, &ip, expiry, false);
	if (rc < 0) {
		cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n",
			 __func__, len, len, hostname);
	else
	} else {
		cifs_dbg(FYI, "%s: resolved: %*.*s to %s expiry %llu\n",
			 __func__, len, len, hostname, *ip_addr,
			 __func__, len, len, hostname, ip,
			 expiry ? (*expiry) : 0);
	return rc;

name_is_IP_address:
	name = kmalloc(len + 1, GFP_KERNEL);
	if (!name)
		return -ENOMEM;
	memcpy(name, hostname, len);
	name[len] = 0;
	cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %s\n",
		 __func__, name);
	*ip_addr = name;
	return 0;
		rc = cifs_convert_address(ip_addr, ip, strlen(ip));
		kfree(ip);

		if (!rc) {
			cifs_dbg(FYI, "%s: unable to determine ip address\n", __func__);
			rc = -EHOSTUNREACH;
		} else
			rc = 0;
	}
	return rc;
}
+3 −1
Original line number Diff line number Diff line
@@ -11,8 +11,10 @@
#ifndef _DNS_RESOLVE_H
#define _DNS_RESOLVE_H

#include <linux/net.h>

#ifdef __KERNEL__
extern int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry);
int dns_resolve_server_name_to_ip(const char *unc, struct sockaddr *ip_addr, time64_t *expiry);
#endif /* KERNEL */

#endif /* _DNS_RESOLVE_H */
Loading