NetTalk IPv6
Introduction
You're likely aware that the internet, and your LAN,
runs on a protocol called TCP/IP. (More accurately the TCP parts do. The
UDP parts run on UDP/IP, but I digress.)
The IP in TCP/IP stands for Internet Protocol. It truly is the
bit underneath everything else that makes the magic happen. You're also
possibly aware that like everything in computer-land, this protocol has
been through several versions in it's life. The version that became the
global standard in the 80's and 90's was IP version 4 (IPv4).
Like all software though, it had to make compromises, and in the 80's that
meant balancing features with the limited memory, and functionality of
devices available at that time. Among many other things this meant 4 bytes
were set aside for addressing a device, and so the completely familiar, 4
byte, IP address (1.2.3.4) was born.
While four billion addresses sounded like a lot in 1980, by the late 90's
it was obvious it wasn't enough. Version 6 of the protocol (IPv6) became
the draft standard in 1998, and ratified as an internet standard in 2017.
The primary difference between IPv4 and IPv6 (from the developer
perspective) is the increase in address size from 32 bits to 128 bits.
This means a LOT more unique addresses. There are other things that matter
as well - routing for example is somewhat easier, and routers have more
resources, so IPv6 traffic tends to be faster than IPv4 traffic - but from
the application perspective it's the address that matters.
In many cases even the address doesn't matter. If you use a DNS name for a
server (say capesoft.com) then this resolves to an IP address. But you
don't see that address, it's handled for you by the networking layer (ie
by NetTalk).
Equally, if you do type in a fixed address instead of a DNS name, then
yes, the address looks a bit different, but it's still just a big number
address (albeit a much bigger number, formatted slightly differently). But
that's really the last time you worry about the address - again the
networking layer (ie NetTalk) takes care of everything for you.
All of this leads up to say that as from NetTalk 14, IPv6 support is
completely baked into the system, and apart from the odd address you
probably won't notice it at all. Under the hood a lot of work has been
done to make this happen, but at the program level you don't really need
to care about it.
Client or Server
NetTalk programs are generally broken down into
Clients and
Servers.
Clients
Clients are things like Email, FTP, WebClients and
so on. They typically connect to a server, using either a DNS name or
specific IP address. These objects are the least affected by this new
support. Given a DNS name they will resolve it, and based on the IP
address returned by the DNS they will connect to it. There's nothing for
you to do, and there are no changes to your program
[1].
If your client program allows the user to type in a DNS address, or an
IP address, then the length of the field should be at least 42
characters long. Since DNS names easily exceed this length, it would be
unusual for a change to your program to be required.
Even if an IPv6 address for a server exists, that does not mean the
client can connect to the server over IPv6. The physical network itself
will determine if that connection is possible, and not all networks (or
computers) today support IPv6. For this reason, by default, NetTalk will
prefer IPv4 if such an address exists. This provides for very good
backward compatibility.
You can choose to prefer IPv6 over IPv4 by using the
Family
property (see
below.)
Note 1: In some cases
programs display the IP number, as a string, to the user. This is
unusual, but possible. In this case the field is usually a String(15) -
since that's the length of a IPv4 numeric address, when expressed as
text. This string should be extended to a String(50) to include a
maximal length IPv6 address, in text format (including the port number).
Servers
Servers are a little more complicated because they
either listen on a specific IP address, or more commonly they
listen on all IP addresses, on a computer.
One server object can listen on IPv4, or IPv6, but not both. (Of course
a procedure can contain multiple objects, so you can code two objects,
one listening on IPv4 and one on IPv6. Or you can run two instances of
your server program.)
If you Bind a server to a specific address then that address format (in
other words the address you use) will determine if the server is
listening on IPv4 or IPv6.
If the server is not bound to a specific address then it will listen on
either all IPv4 or all IPv6 addresses. One server
object listens on either IPv4 or IPv6, not both. Which one it listens on
depends on the Family property.
Family
NetTalk objects (servers and clients) connect over
IPv6 or IPv4. However they only communicate on one or the other, not both
[2].
Client
A Client program connects to the server over IPv4 or
IPv6, not both at the same time.
To distinguish which IP Version you want to use, a new property, called
Family has been created. This is a Long,
and should be set to one of the following values;
Net:IPvAuto, Net:IPv4
or Net:IPv6. The default value is Net:IPvAuto.
The default is the best option in most circumstances, so for most
client's there is literally nothing to do.
This property is implemented at the NetSimple level, and so all classes
derived from NetSimple (Email, WebClient, WebServer, FTP and so on) can
be forced into IPv6 mode simply by setting;
whatever.family = Net:IPv6
But wait, there's more;
All client classes take a Server Name as a parameter. This server name
is usually a domain name, for example capesoft.com.
By default, and if Family is set to Net:IPvAuto
or Net:IPv4 then an IPv4 DNS Lookup will
happen on this name first. If there is no DNS A record for this
name (ie an IPv4 record), then an IPv6 DNS lookup for a DNS AAAA record
will be made. If this is successful, then the client will attempt to
connect to the IPv6 address. Bear in mind that this is just the DNS
lookup. There is no guarantee the connection will then work - since the
network may not be correctly setup to support IPv6.
If the domain name is not a DNS address, but rather a fixed IP address
(like say 127.0.0.1 or ::1)
then it will override the Family property
and the Family property will be set based
on that address. In other words if an IPv4 address is specified (of the
form a.b.c.d) then the client will connect
using IPv4. If an IPv6 address is specified (of the form a:b:c:d:e:f:g:h)
then the client will attempt to connect using IPv6. Again, this
connection will fail if the network is not correctly configured for
IPv6.
Server
Server objects use the same property, which then has
the same values.
Sserver objects can be bound to a specific IP address. If the server is
bound to an IP address then the Family property is inherited from the
format of the IP address.
IPv4 Addresses mean it is listening on IPv4, IPv6 addresses mean it is
listening on IPv6. This overrides whatever value has been set in Family.
(More accurately, the Family property is set to match
this address format.)
If the Family property is not set in a server, and a server bind address
is not set, then the server will listen on all IPv4 addresses.
notes
Note 2: One
possible development strategy was to have the object listen on both IPv4
and IPv6 at the same time. It's technically possible, by creating two
connections, but would result in a lot of (your) existing embed code
needing to be tweaked. Since the only practical benefit are Server
programs, which mostly means the WebServer, we've rather adopted the
more conservative route of requiring two programs, or objects, for now.
This has some spin-off benefits for the web server - by isolating IPv4
and IPv6 into separate programs they can (collectively) use more RAM,
and a crash in one would not bring down the other.
In the WebServer you can force the server into IPv4 mode using the
command line switch
/IPv4 and into IPv6
mode using the switch
/IPv6. The exact same
Exe can thus be run twice, from the same location, using the same
settings file, simply by using the command line parameter. For more on
command line settings see the
Runtime
Settings document.
Address Format
IPv4 addresses are instantly recognizable. They
consist of 4 (up to) 3 digit decimal numbers separated by periods. For
example
127.0.0.1. A colon is used to
separate the port number if a port is included. For example
127.0.0.1:88.
IPv6 addresses are longer, since they contain more bits. The differences
between IPv4 formatting and IPv6 formatting are;
- 8 numbers, in the list, not 4
- separated by colons (:) not periods (.)
- in hexadecimal format, not decimal
- 2 bytes per number, not 1.
So in other words a number like this;
fe80:0000:0000:0000:caec:87ae:3fba:1c00
yes, it's hexadecimal, yes it's a lot longer, and I agree, you won't be
remembering them in your head much.
But wait, there's more;
Because you may want to include the port number, it's common to wrap the
IP address part in [ ] to separate it from the port number. So if the port
number is 88, then the address becomes;
[fe80:0000:0000:0000:caec:87ae:3fba:1c00]:88
Also, as you might imagine, it's fairly common to have a run of 0's, and 0
blocks. These can be condensed using a double-colon;
[fe80::caec:87ae:3fba:1c00]:88
Only one such condensation in the address is allowed.
LocalHost
One address you will remember is the one for
localhost. In IPv4 this is 127.0.0.1, in
IPv6 it's ::1. (Which is the condensed
version of 0000:0000:0000:0000:0000:0000:0000:0001)
Amazon EC2
Amazon EC2 supports IPv6, however it is not on by
default, and it's "somewhat" convoluted setting it up.
There is no shortage of web articles on doing this, so feel free to Google
to more information on that. Doubtless the process will change from time
to time.
The process itself seems a bit bonkers, because you need to set up your
Amazon Private Cloud first, and tweak some Security groups. After that
it's not too bad per-machine. I found this link useful
https://4sysops.com/archives/assign-an-ipv6-address-to-an-ec2-instance-dual-stack/