From: Kinglong Mee <kinglongmee@gmail.com>
To: "J. Bruce Fields" <bfields@fieldses.org>
Cc: linux-nfs@vger.kernel.org, kinglongmee@gmail.com
Subject: [PATCH] NFS4.0: Add IPv6 support
Date: Sat, 17 May 2014 18:47:04 +0800 [thread overview]
Message-ID: <53773E28.5010206@gmail.com> (raw)
Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
---
nfs4.0/lib/rpc/rpc.py | 15 ++++++++-----
nfs4.0/nfs4lib.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++
nfs4.0/testserver.py | 26 +++++-----------------
3 files changed, 77 insertions(+), 25 deletions(-)
diff --git a/nfs4.0/lib/rpc/rpc.py b/nfs4.0/lib/rpc/rpc.py
index 60f70bd..8b39df4 100644
--- a/nfs4.0/lib/rpc/rpc.py
+++ b/nfs4.0/lib/rpc/rpc.py
@@ -188,6 +188,9 @@ class RPCClient(object):
self.debug = 0
t = threading.currentThread()
self.lock = threading.Lock()
+ self.af = socket.AF_INET;
+ if host.find(':') != -1:
+ self.af = socket.AF_INET6;
self.remotehost = host
self.remoteport = port
self.timeout = timeout
@@ -207,6 +210,7 @@ class RPCClient(object):
self._init_security(self.sec_list) # Note this can make calls
self.security = sec_list[0]
+
def _init_security(self, list):
# Each element of list must have functions:
# initialize, secure_data, make_cred, make_verf
@@ -235,8 +239,7 @@ class RPCClient(object):
if t in self._socket:
out = self._socket[t]
else:
- out = self._socket[t] = socket.socket(socket.AF_INET,
- socket.SOCK_STREAM)
+ out = self._socket[t] = socket.socket(self.af, socket.SOCK_STREAM)
if self.uselowport:
self.bindsocket(out)
out.connect((self.remotehost, self.remoteport))
@@ -301,8 +304,7 @@ class RPCClient(object):
t = threading.currentThread()
self.lock.acquire()
self._socket[t].close()
- out = self._socket[t] = socket.socket(socket.AF_INET,
- socket.SOCK_STREAM)
+ out = self._socket[t] = socket.socket(self.af, socket.SOCK_STREAM)
# out.bind
out.connect((self.remotehost, self.remoteport))
out.settimeout(self.timeout)
@@ -454,7 +456,10 @@ class RPCClient(object):
class Server(object):
def __init__(self, host='', port=51423, name="SERVER"):
- self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ self.s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+ except:
+ self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((host, port))
self.port = self.s.getsockname()[1]
diff --git a/nfs4.0/nfs4lib.py b/nfs4.0/nfs4lib.py
index 5fc7bf3..994e0e1 100644
--- a/nfs4.0/nfs4lib.py
+++ b/nfs4.0/nfs4lib.py
@@ -39,6 +39,7 @@ import time
import struct
import socket
import sys
+import re
class NFSException(rpc.RPCError):
pass
@@ -1013,4 +1014,64 @@ def bitmap2list(bitmap):
bitmap >>= 1
return out
+def path_components(path, use_dots=True):
+ """Convert a string '/a/b/c' into an array ['a', 'b', 'c']"""
+ out = []
+ for c in path.split('/'):
+ if c == '':
+ pass
+ elif use_dots and c == '.':
+ pass
+ elif use_dots and c == '..':
+ del out[-1]
+
+def parse_nfs_url(url):
+ """Parse [nfs://]host:port/path, format taken from rfc 2224
+ multipath addr:port pair are as such:
+
+ $ip1:$port1,$ip2:$port2..
+
+ Returns triple server, port, path.
+ """
+ p = re.compile(r"""
+ (?:nfs://)? # Ignore an optionally prepended 'nfs://'
+ (?P<servers>[^/]+)
+ (?P<path>/.*)? # set path=everything else, must start with /
+ $
+ """, re.VERBOSE)
+
+ m = p.match(url)
+ if m:
+ servers = m.group('servers')
+ server_list = []
+
+ for server in servers.split(','):
+ server = server.strip()
+
+ idx = server.rfind(':')
+ bracket_idx = server.rfind(']')
+
+ # the first : is before ipv6 addr ] -> no port specified
+ if bracket_idx > idx:
+ idx = -1
+
+ if idx >= 0:
+ host = server[:idx]
+ port = server[idx+1:]
+ else:
+ host = server
+ port = None
+
+ # remove brackets around IPv6 addrs, if they exist
+ if host.startswith('[') and host.endswith(']'):
+ host = host[1:-1]
+
+ port = (2049 if not port else int(port))
+ server_list.append((host, port))
+ path = m.group('path')
+ path = (path_components(path) if path else [])
+
+ return tuple(server_list), path
+ else:
+ raise ValueError("Error parsing NFS URL: %s" % url)
diff --git a/nfs4.0/testserver.py b/nfs4.0/testserver.py
index 606e2f0..41be74a 100755
--- a/nfs4.0/testserver.py
+++ b/nfs4.0/testserver.py
@@ -35,7 +35,6 @@ if __name__ == "__main__":
if os.path.isfile(os.path.join(sys.path[0], 'lib', 'testmod.py')):
sys.path.insert(1, os.path.join(sys.path[0], 'lib'))
-import re
import nfs4lib
import testmod
from optparse import OptionParser, OptionGroup, IndentedHelpFormatter
@@ -57,23 +56,6 @@ if not hasattr(os, "getgid"):
else:
GID = os.getgid()
-
-def parse_url(url):
- """Parse [nfs://]host:port/path"""
- p = re.compile(r"""
- (?:nfs://)? # Ignore an optionally prepended 'nfs://'
- (?P<host>[^:]+) # set host=everything up to next :
- :?
- (?P<port>[^/]*) # set port=everything up to next /
- (?P<path>/.*$|$) # set path=everything else
- """, re.VERBOSE)
-
- m = p.match(url)
- if m:
- return m.group('host'), m.group('port'), m.group('path')
- else:
- return None, None, None
-
def unixpath2comps(str, pathcomps=None):
if pathcomps is None or str[0] == '/':
pathcomps = []
@@ -284,9 +266,13 @@ def main():
if not args:
p.error("Need a server")
url = args.pop(0)
- opt.server, opt.port, opt.path = parse_url(url)
- if not opt.server:
+ server_list, opt.path = nfs4lib.parse_nfs_url(url)
+
+ if not server_list:
p.error("%s not a valid server name" % url)
+
+ opt.server, opt.port = server_list[0]
+
if not opt.port:
opt.port = 2049
else:
--
1.9.0
reply other threads:[~2014-05-17 10:47 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53773E28.5010206@gmail.com \
--to=kinglongmee@gmail.com \
--cc=bfields@fieldses.org \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.