@@ -1446,25 +1446,32 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
{
struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
+ unsigned short int port;
+
+ /* search for a connection with the default port if user doesn't
+ specify the port manually */
+ port = htons(CIFS_PORT);
switch (addr->sa_family) {
case AF_INET:
+ if (addr4->sin_port)
+ port = addr4->sin_port;
if (addr4->sin_addr.s_addr !=
server->addr.sockAddr.sin_addr.s_addr)
return false;
- if (addr4->sin_port &&
- addr4->sin_port != server->addr.sockAddr.sin_port)
+ if (port != server->addr.sockAddr.sin_port)
return false;
break;
case AF_INET6:
+ if (addr6->sin6_port)
+ port = addr6->sin6_port;
if (!ipv6_addr_equal(&addr6->sin6_addr,
&server->addr.sockAddr6.sin6_addr))
return false;
if (addr6->sin6_scope_id !=
server->addr.sockAddr6.sin6_scope_id)
return false;
- if (addr6->sin6_port &&
- addr6->sin6_port != server->addr.sockAddr6.sin6_port)
+ if (port != server->addr.sockAddr6.sin6_port)
return false;
break;
}
@@ -2126,7 +2133,7 @@ ipv4_connect(struct TCP_Server_Info *server)
int rc = 0;
int val;
bool connected = false;
- __be16 orig_port = 0;
+ bool orig_port_error = false;
struct socket *socket = server->ssocket;
if (socket == NULL) {
@@ -2148,32 +2155,30 @@ ipv4_connect(struct TCP_Server_Info *server)
if (rc < 0)
return rc;
- /* user overrode default port */
+ /* user overrode default port or we perform reconnect */
if (server->addr.sockAddr.sin_port) {
rc = socket->ops->connect(socket, (struct sockaddr *)
&server->addr.sockAddr,
sizeof(struct sockaddr_in), 0);
if (rc >= 0)
connected = true;
+ else
+ orig_port_error = true;
+ /* in this case we don't have to try other port
+ because we can mount another share */
}
- if (!connected) {
- /* save original port so we can retry user specified port
- later if fall back ports fail this time */
- orig_port = server->addr.sockAddr.sin_port;
-
- /* do not retry on the same port we just failed on */
- if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
- server->addr.sockAddr.sin_port = htons(CIFS_PORT);
- rc = socket->ops->connect(socket,
- (struct sockaddr *)
- &server->addr.sockAddr,
- sizeof(struct sockaddr_in), 0);
- if (rc >= 0)
- connected = true;
- }
+ if (!orig_port_error && !connected) {
+ server->addr.sockAddr.sin_port = htons(CIFS_PORT);
+ rc = socket->ops->connect(socket,
+ (struct sockaddr *)
+ &server->addr.sockAddr,
+ sizeof(struct sockaddr_in), 0);
+ if (rc >= 0)
+ connected = true;
}
- if (!connected) {
+
+ if (!orig_port_error && !connected) {
server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
rc = socket->ops->connect(socket, (struct sockaddr *)
&server->addr.sockAddr,
@@ -2185,15 +2190,12 @@ ipv4_connect(struct TCP_Server_Info *server)
/* give up here - unless we want to retry on different
protocol families some day */
if (!connected) {
- if (orig_port)
- server->addr.sockAddr.sin_port = orig_port;
cFYI(1, "Error %d connecting to server via ipv4", rc);
sock_release(socket);
server->ssocket = NULL;
return rc;
}
-
/*
* Eventually check for other socket options to change from
* the default. sock_setsockopt not used because it expects
@@ -2291,7 +2293,7 @@ ipv6_connect(struct TCP_Server_Info *server)
int rc = 0;
int val;
bool connected = false;
- __be16 orig_port = 0;
+ bool orig_port_error = false;
struct socket *socket = server->ssocket;
if (socket == NULL) {
@@ -2314,31 +2316,29 @@ ipv6_connect(struct TCP_Server_Info *server)
if (rc < 0)
return rc;
- /* user overrode default port */
+ /* user overrode default port or we perform reconnect */
if (server->addr.sockAddr6.sin6_port) {
rc = socket->ops->connect(socket,
(struct sockaddr *) &server->addr.sockAddr6,
sizeof(struct sockaddr_in6), 0);
if (rc >= 0)
connected = true;
+ else
+ orig_port_error = true;
+ /* in this case we don't have to try other port
+ because we can mount another share */
}
- if (!connected) {
- /* save original port so we can retry user specified port
- later if fall back ports fail this time */
-
- orig_port = server->addr.sockAddr6.sin6_port;
- /* do not retry on the same port we just failed on */
- if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
- server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
- rc = socket->ops->connect(socket, (struct sockaddr *)
- &server->addr.sockAddr6,
- sizeof(struct sockaddr_in6), 0);
- if (rc >= 0)
- connected = true;
- }
+ if (!orig_port_error && !connected) {
+ server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
+ rc = socket->ops->connect(socket, (struct sockaddr *)
+ &server->addr.sockAddr6,
+ sizeof(struct sockaddr_in6), 0);
+ if (rc >= 0)
+ connected = true;
}
- if (!connected) {
+
+ if (!orig_port_error && !connected) {
server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
rc = socket->ops->connect(socket, (struct sockaddr *)
&server->addr.sockAddr6,
@@ -2350,8 +2350,6 @@ ipv6_connect(struct TCP_Server_Info *server)
/* give up here - unless we want to retry on different
protocol families some day */
if (!connected) {
- if (orig_port)
- server->addr.sockAddr6.sin6_port = orig_port;
cFYI(1, "Error %d connecting to server via ipv6", rc);
sock_release(socket);
server->ssocket = NULL;