IPv6 patch for Samba 2.2.3a is available

Nathan Lutchansky lutchann-sambatech at litech.org
Wed Apr 17 22:07:01 GMT 2002

I've finished patching Samba 2.2.3a to enable SMB connections over IPv6.
The patch is quite lengthy, almost 3000 lines, so I have not included it 
here.  It may be retrieved from <http://v6web.litech.org/samba/>.

Below is a description of the changes that were made in the code.  I 
encourage developers to review this description and offer suggestions 
and improvements for the patch, so that I may adapt the patch to CVS HEAD 
for inclusion in the official source tree.  -Nathan


Architecturally, the biggest modification necessary was the support for
address lists.  Since servers may have both IPv6 and IPv4 addresses and
the IPv6 address isn't necessarily reachable to all clients, hosts to
which an SMB connection are to be made are now represented by a linked
list of sockaddr structs.  The resolve_name() function was broken into one 
function to support NetBIOS and one to support sockaddr lists, and the 
cli_connect() function and friends were changed to take sockaddr lists.  
Also, a few changes were made in smbd access control to handle PF_INET6 
sockets and sockaddr_in6 endpoints.

Name resolution

Since NetBIOS still relies heavily on IPv4, the parts of the source that
talk NetBIOS still use IPv4 addresses exclusively, but code that talks TCP
and may use direct-hosted SMB was modified.  This required breaking out
name resolution into two sets of functions: instead of resolve_name() we
have resolve_name_netbios(), which functions like the old resolve_name(),
and resolve_name_smb() which returns a sockaddr list.

The new resolve_name_smb() function will still perform 0x20 lookups in
wins, broadcast, etc, but will also look for AAAA and A6 DNS records using
the getaddrinfo() libc function.  Additionally, since sockaddrs contain a
port number, resolve_name_smb() takes a port number as an argument that it
will include with returned addresses.  If the passed port number is 0, it
will return two sockaddrs for each IPv4 address; one with port 445 and one
with port 139, causing both ports to be tried during connection attempts.  
Obviously, only port 445 is used for IPv6 addresses.

Client functions

To accomodate the new sockaddr lists, the cli_connect() and 
cli_establish_connection() functions were updated to take an address list 
rather than a struct in_addr.  As with passing in ipzero before, passing 
in a NULL will cause the functions to perform a resolve_name_smb() on the 
server name.

On the back end, open_socket_out takes a sockaddr list of addresses to
attempt to connect to, and it tries each one in order until one succeeds.  
Errors during connecting that indicate that IPv6 is being attempted but is
not available, such as "host unreachable" or "protocol not available", are
merely logged at a high debugging level and otherwise ignored, unless the
attempt was to the last (or only) address in the list.  This behavior
allows clients with only IPv4 connectivity to connect to servers with both
types of addresses without the client complaining or failing.

Client configuration

The libsmb client structure was modified to store the destination address
as a sockaddr list, with a member pointer "connected_addr" pointing at the
sockaddr element in the destination sockaddr list to which the client is 
actually connected.

Since the TCP port number is built into the name resolution now, the usage
of the cli_set_port() function has changed.  The only reason
cli_set_port() should be called now is if we are connecting to a
*non-standard* port, and we intend to call cli_connect() with a NULL
sockaddr list.  The default is to connect to port 445 followed by 139, and
to erroneously call cli_set_port() with 139 would cause connections to
*only* go to port 139, which is probably not what we want, and is
completely broken for IPv6 hosts.


Surprisingly few changes were necessary to prepare smbd for incoming IPv6 
connections.  Many improvements to the get_socket_name() and 
get_socket_addr() functions were necessary to add support for struct 
sockaddr_in6 endpoints, but the interface and behavior of the functions 
did not change.

The masked_match() function for implementing IP address prefix matching
was broken into an IPv4 version and an IPv6 version.  The IPv4 version
functions as it did before, taking tokens like, 
whereas the IPv6 version takes standard IPv6 prefixes like 3ffe:ffff::/32.

As with unpatched Samba, accepting connections on port 445 with either 
IPv4 or IPv6 requires starting smbd from inetd or a work-alike.  Of 
course, accepting IPv6 connections requires an IPv6-enabled daemon like 
xinetd or rlinetd.

Unfinished business

There are a number of places in the code where ismyip() is called to 
determine if we're attempting to connect to ourselves and create a loop.  
I don't know the best (portable) way to determine whether IPv6 addresses 
belong to us, so these sections of code are wrapped in #if 0.


The parts of the code that require an IPv6-capable API on the host are 
wrapped in #ifdef HAVE_INET6, which is defined by the configure script if 
the user specifies --with-ipv6.  If this flag is present, some specific 
checks are made to make sure the correct structures and functions are 
present.  I've tried to write the code to minimize use of features that 
are found to be broken or incorrectly implemented in many places, so 
configure only checks for a few things.

The code is written so that the --with-ipv6 flag doesn't change the
apparent behavior of the applications.  On most sane systems, --with-ipv6
may be used even by users who are unaware of IPv6, but it's best to err on
the side of caution since some getaddrinfo() implementations, particularly
the one currently shipping in Mac OSX, aren't extensively tested and may
not be relied upon to perform correctly.

| Nathan Lutchansky | lutchann at litech.org |  Lithium Technologies  |
|  I dread success.  To have succeeded is to have finished one's   |
|  business on earth...  I like a state of continual becoming,     |
|  with a goal in front and not behind. - George Bernard Shaw      |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20020417/eec9d3bb/attachment.bin

More information about the samba-technical mailing list