mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
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: Paulo Alcantara (SUSE) <pc@cjr.nz> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
2301bc103a
commit
6d740164d8
@ -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.
|
||||
*/
|
||||
ttl = max_t(unsigned long, expiry - now, SMB_DNS_RESOLVE_INTERVAL_MIN) + 1;
|
||||
}
|
||||
rc = !rc ? -1 : 0;
|
||||
now = ktime_get_real_seconds();
|
||||
if (expiry && expiry > now)
|
||||
/* 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;
|
||||
|
||||
requeue_resolve:
|
||||
cifs_dbg(FYI, "%s: next dns resolution scheduled for %lu seconds in the future\n",
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
cifs_server_unlock(server);
|
||||
}
|
||||
cifs_server_lock(server);
|
||||
match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss);
|
||||
cifs_server_unlock(server);
|
||||
|
||||
kfree(ip);
|
||||
return match;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -1258,44 +1258,28 @@ int match_target_ip(struct TCP_Server_Info *server,
|
||||
bool *result)
|
||||
{
|
||||
int rc;
|
||||
char *target, *tip = NULL;
|
||||
struct sockaddr tipaddr;
|
||||
char *target;
|
||||
struct sockaddr_storage ss;
|
||||
|
||||
*result = false;
|
||||
|
||||
target = kzalloc(share_len + 3, GFP_KERNEL);
|
||||
if (!target) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (!target)
|
||||
return -ENOMEM;
|
||||
|
||||
scnprintf(target, share_len + 3, "\\\\%.*s", (int)share_len, share);
|
||||
|
||||
cifs_dbg(FYI, "%s: target name: %s\n", __func__, target + 2);
|
||||
|
||||
rc = dns_resolve_server_name_to_ip(target, &tip, NULL);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
cifs_dbg(FYI, "%s: target ip: %s\n", __func__, tip);
|
||||
|
||||
if (!cifs_convert_address(&tipaddr, tip, strlen(tip))) {
|
||||
cifs_dbg(VFS, "%s: failed to convert target ip address\n",
|
||||
__func__);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr,
|
||||
&tipaddr);
|
||||
cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result);
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
rc = dns_resolve_server_name_to_ip(target, (struct sockaddr *)&ss, NULL);
|
||||
kfree(target);
|
||||
kfree(tip);
|
||||
|
||||
return rc;
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
*result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss);
|
||||
cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix)
|
||||
|
Loading…
Reference in New Issue
Block a user