Sunday, September 5, 2010

what is port number??



1.       In computer networking, a port is an application-specific or process-specific software construct serving as a communications endpoint used by Transport Layer protocols of the Internet Protocol Suite, such as Transmission Control Protocol (TCP) and User Datagram Protocol (UDP)
2.       A field in the TCP & UDP headers that specifies which applications are sending & receiving the messages. The port field is the layer interface that enables TCP & UDP to transfer messages to any application.
3.       A port number is a number assigned to a particular network service on a host. For example, SMTP usually uses port 25, while HTTP is usually port 80.
4.       A field in a TCP or UDP header that identifies the application that either sent (source port) or should receive (destination port) the data inside the data segment.
5.       A port number identifies both a computer and also a "channel" within that computer where network communication will take place.
6.       In computer networking, a port number is part of the addressing information used to identify the senders and receivers of messages. Port numbers are most commonly used with TCP/IP connections. Home network routers and computer software work with ports and sometimes allow you to configure port number settings. These port numbers allow different applications on the same computer to share network resources simultaneously.
7.       Port numbers are associated with network addresses. For example, in TCP/IP networking, both TCP and UDP utilize their own set of ports that work together with IP addresses.
8.       Port numbers work like telephone extensions. Just as a business telephone switchboard can use a main phone number and assign each employee an extension number (like x100, x101, etc.), so a computer has a main address and a set of port numbers to handle incoming and outgoing connections.
9.       In both TCP and UDP, port numbers start at 0 and go up to 65535. Numbers in the lower ranges are dedicated to common Internet protocols (like 21 for FTP, 80 for HTTP, etc.).


In computer networking, a port is an application-specific or process-specific software construct serving as a communications endpoint. It is used by Transport Layer protocols of the Internet Protocol Suite, such as Transmission Control Protocol (TCP) and User Datagram Protocol (UDP). A specific port is identified by its number, commonly known as the port number, the IP address with which it is associated, and the protocol used for communication.
A well-known range of port numbers is reserved by convention to identify specific service types on a host computers. In the client-server model of application architecture this is used to provide a multiplexing service on each port number that network clients connect to for service initiation, after which communication is reestablished on other connection-specific port numbers.
Examples
An example for the use of ports is the Internet mail system. A server used for sending and receiving email generally needs two services. The first service is used to transport email to and from other servers. This is accomplished with the Simple Mail Transfer Protocol (SMTP). The SMTP service application usually listens on TCP port 25 for incoming requests. The second service is the Post Office Protocol (POP) which is used by e-mail client applications on user's personal computers to fetch email messages from the server. The POP service listens on TCP port number 110. Both services may be running on the same host computer, in which case the port number distinguishes the service that was requested by a remote computer, be it a user's computer or another mail server.
While the listening port number of a server is well defined (IANA calls these the well known ports), the client's port number is often chosen from the dynamic port range (see below). In some applications, the client and the server each use specific port numbers assigned by the IANA. A good example of this is DHCP in which the client always uses UDP port 68 and the server always uses UDP port 67.

unix domain sockets vs. internet sockets

> I am coding a daemon program. I am not sure about which type of sockets> 
i should use. Could you compare ip sockets and unix domain sockets? 
My> main criterions are performance and protocol load.
 What are the> differences between impelementations of them at kernel level?
There are a few differences that might be of interest, in addition to the
already pointed out difference that if you start out using IP sockets, you
don't have to migrate to them later when you want inter-machine
connectivity: 

- UNIX domain sockets use the file system as the address name space.  This
  means you can use UNIX file permissions to control access to communicate
  with them.  I.e., you can limit what other processes can connect to the
  daemon -- maybe one user can, but the web server can't, or the like.
  With IP sockets, the ability to connect to your daemon is exposed off
  the current system, so additional steps may have to be taken for
  security.  On the other hand, you get network transparency.  With UNIX
  domain sockets, you can actually retrieve the credential of the process
  that created the remote socket, and use that for access control also,
  which can be quite convenient on multi-user systems.

- IP sockets over localhost are basically looped back network on-the-wire
  IP.  There is intentionally "no special knowledge" of the fact that the
  connection is to the same system, so no effort is made to bypass the
  normal IP stack mechanisms for performance reasons.  For example,
  transmission over TCP will always involve two context switches to get to
  the remote socket, as you have to switch through the netisr, which
  occurs following the "loopback" of the packet through the synthetic
  loopback interface.  Likewise, you get all the overhead of ACKs, TCP
  flow control, encapsulation/decapsulation, etc.  Routing will be
  performed in order to decide if the packets go to the localhost.
  Large sends will have to be broken down into MTU-size datagrams, which
  also adds overhead for large writes.  It's really TCP, it just goes over
  a loopback interface by virtue of a special address, or discovering that
  the address requested is served locally rather than over an ethernet
  (etc). 

- UNIX domain sockets have explicit knowledge that they're executing on
  the same system.  They avoid the extra context switch through the
  netisr, and a sending thread will write the stream or datagrams directly
  into the receiving socket buffer.  No checksums are calculated, no
  headers are inserted, no routing is performed, etc.  Because they have
  access to the remote socket buffer, they can also directly provide
  feedback to the sender when it is filling, or more importantly,
  emptying, rather than having the added overhead of explicit
  acknowledgement and window changes.  The one piece of functionality that
  UNIX domain sockets don't provide that TCP does is out-of-band data.  In
  practice, this is an issue for almost noone.

In general, the argument for implementing over TCP is that it gives you
location independence and immediate portability -- you can move the client
or the daemon, update an address, and it will "just work".  The sockets
layer provides a reasonable abstraction of communications services, so
it's not hard to write an application so that the connection/binding
portion knows about TCP and UNIX domain sockets, and all the rest just
uses the socket it's given.  So if you're looking for performance locally,
I think UNIX domain sockets probably best meet your need.  Many people
will code to TCP anyway because performance is often less critical, and
the network portability benefit is substantial.

Right now, the UNIX domain socket code is covered by a subsystem lock; I
have a version that used more fine-grain locking, but have not yet
evaluated the performance impact of those changes.  I've you're running in
an SMP environment with four processors, it could be that those changes
might positively impact performance, so if you'd like the patches, let me
know.  Right now they're on my schedule to start testing, but not on the
path for inclusion in FreeBSD 5.4.  The primary benefit of greater
granularity would be if you had many pairs of threads/processes
communicating across processors using UNIX domain sockets, and as a result
there was substantial contention on the UNIX domain socket subsystem lock. 
The patches don't increase the cost of normal send/receive operations, but
due add extra mutex operations in the listen/accept/connect/bind paths.

Unix domain socket or IPC socket

A Unix domain socket or IPC socketinter-process communication socket) is a data communications endpoint for exchanging data between processes executing within the same host operating system. While similar in functionality to named pipes, Unix domain sockets may be created as byte streams or as datagram sequences, while pipes are byte streams only. Processes using Unix domain sockets do not need to share a common ancestry. The programmer's application interface (API) for Unix domain sockets is similar to that of an Internet socket, but does not use an underlying network protocol for communication. The Unix domain socket facility is a standard component of POSIX operating systems.
UNIX domain sockets use the file system as address name space. They are referenced by processes as inodes in the file system. This allows two processes to open the same socket in order to communicate. However, communication occurs entirely within the operating system kernel.
In addition to sending data, processes may send file descriptors across a Unix domain socket connection using the sendmsg() and recvmsg() system calls.

Unix Sockets

11. Unix Sockets


Remember FIFOs? Remember how they can only send data in one direction, just like a Pipes? Wouldn't it be grand if you could send data in both directions like you can with a socket?
Well, hope no longer, because the answer is here: Unix Domain Sockets! In case you're still wondering what a socket is, well, it's a two-way communications pipe, which can be used to communicate in a wide variety of domains. One of the most common domains sockets communicate over is the Internet, but we won't discuss that here. We will, however, be talking about sockets in the Unix domain; that is, sockets that can be used between processes on the same Unix system.
Unix sockets use many of the same function calls that Internet sockets do, and I won't be describing all of the calls I use in detail within this document. If the description of a certain call is too vague (or if you just want to learn more about Internet sockets anyway), I arbitrarily suggest Beej's Guide to Network Programming using Internet Sockets. I know the author personally.

11.1. Overview

Like I said before, Unix sockets are just like two-way FIFOs. However, all data communication will be taking place through the sockets interface, instead of through the file interface. Although Unix sockets are a special file in the file system (just like FIFOs), you won't be using open() and read()—you'll be using socket(), bind(), recv(), etc.
When programming with sockets, you'll usually create server and client programs. The server will sit listening for incoming connections from clients and handle them. This is very similar to the situation that exists with Internet sockets, but with some fine differences.
For instance, when describing which Unix socket you want to use (that is, the path to the special file that is the socket), you use a struct sockaddr_un, which has the following fields:
struct sockaddr_un {
    unsigned short sun_family;  /* AF_UNIX */
    char sun_path[108];
}
This is the structure you will be passing to the bind() function, which associates a socket descriptor (a file descriptor) with a certain file (the name for which is in the sun_path field).

11.2. What to do to be a Server

Without going into too much detail, I'll outline the steps a server program usually has to go through to do it's thing. While I'm at it, I'll be trying to implement an "echo server" which just echos back everything it gets on the socket.
Here are the server steps:
  1. Call socket(): A call to socket() with the proper arguments creates the Unix socket:
    unsigned int s, s2;
    struct sockaddr_un local, remote;
    int len;
    
    s = socket(AF_UNIX, SOCK_STREAM, 0);
    The second argument, SOCK_STREAM, tells socket() to create a stream socket. Yes, datagram sockets (SOCK_DGRAM) are supported in the Unix domain, but I'm only going to cover stream sockets here. For the curious, see Beej's Guide to Network Programming for a good description of unconnected datagram sockets that applies perfectly well to Unix sockets. The only thing that changes is that you're now using a struct sockaddr_un instead of a struct sockaddr_in.
    One more note: all these calls return -1 on error and set the global variable errno to reflect whatever went wrong. Be sure to do your error checking.
  2. Call bind(): You got a socket descriptor from the call to socket(), now you want to bind that to an address in the Unix domain. (That address, as I said before, is a special file on disk.)
    local.sun_family = AF_UNIX;  /* local is declared before socket() ^ */
    strcpy(local.sun_path, "/home/beej/mysocket");
    unlink(local.sun_path);
    len = strlen(local.sun_path) + sizeof(local.sun_family);
    bind(s, (struct sockaddr *)&local, len);
    This associates the socket descriptor "s" with the Unix socket address "/home/beej/mysocket". Notice that we called unlink() before bind() to remove the socket if it already exists. You will get an EINVAL error if the file is already there.
  3. Call listen(): This instructs the socket to listen for incoming connections from client programs:
    listen(s, 5);
    The second argument, 5, is the number of incoming connections that can be queued before you call accept(), below. If there are this many connections waiting to be accepted, additional clients will generate the error ECONNREFUSED.
  4. Call accept(): This will accept a connection from a client. This function returns another socket descriptor! The old descriptor is still listening for new connections, but this new one is connected to the client:
    len = sizeof(struct sockaddr_un);
    s2 = accept(s, &remote, &len);
    When accept() returns, the remote variable will be filled with the remote side's struct sockaddr_un, and len will be set to its length. The descriptor s2 is connected to the client, and is ready for send() and recv(), as described in the Network Programming Guide.
  5. Handle the connection and loop back to accept(): Usually you'll want to communicate to the client here (we'll just echo back everything it sends us), close the connection, then accept() a new one.
    while (len = recv(s2, &buf, 100, 0), len > 0)
        send(s2, &buf, len, 0);
    
    /* loop back to accept() from here */
  6. Close the connection: You can close the connection either by calling close(), or by calling shutdown().
With all that said, here is some source for an echoing server, echos.c. All it does is wait for a connection on a Unix socket (named, in this case, "echo_socket").
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "echo_socket"

int main(void)
{
    int s, s2, t, len;
    struct sockaddr_un local, remote;
    char str[100];

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    local.sun_family = AF_UNIX;
    strcpy(local.sun_path, SOCK_PATH);
    unlink(local.sun_path);
    len = strlen(local.sun_path) + sizeof(local.sun_family);
    if (bind(s, (struct sockaddr *)&local, len) == -1) {
        perror("bind");
        exit(1);
    }

    if (listen(s, 5) == -1) {
        perror("listen");
        exit(1);
    }

    for(;;) {
        int done, n;
        printf("Waiting for a connection...\n");
        t = sizeof(remote);
        if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
            perror("accept");
            exit(1);
        }

        printf("Connected.\n");

        done = 0;
        do {
            n = recv(s2, str, 100, 0);
            if (n <= 0) {
                if (n < 0) perror("recv");
                done = 1;
            }

            if (!done) 
                if (send(s2, str, n, 0) < 0) {
                    perror("send");
                    done = 1;
                }
        } while (!done);

        close(s2);
    }

    return 0;
}
As you can see, all the aforementioned steps are included in this program: call socket(), call bind(), call listen(), call accept(), and do some network send()s and recv()s.

11.3. What to do to be a client

There needs to be a program to talk to the above server, right? Except with the client, it's a lot easier because you don't have to do any pesky listen()ing or accept()ing. Here are the steps:
  1. Call socket() to get a Unix domain socket to communicate through.
  2. Set up a struct sockaddr_un with the remote address (where the server is listening) and call connect() with that as an argument
  3. Assuming no errors, you're connected to the remote side! Use send() and recv() to your heart's content!
How about code to talk to the echo server, above? No sweat, friends, here is echoc.c:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "echo_socket"

int main(void)
{
    int s, t, len;
    struct sockaddr_un remote;
    char str[100];

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    printf("Trying to connect...\n");

    remote.sun_family = AF_UNIX;
    strcpy(remote.sun_path, SOCK_PATH);
    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
    if (connect(s, (struct sockaddr *)&remote, len) == -1) {
        perror("connect");
        exit(1);
    }

    printf("Connected.\n");

    while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) {
        if (send(s, str, strlen(str), 0) == -1) {
            perror("send");
            exit(1);
        }

        if ((t=recv(s, str, 100, 0)) > 0) {
            str[t] = '\0';
            printf("echo> %s", str);
        } else {
            if (t < 0) perror("recv");
            else printf("Server closed connection\n");
            exit(1);
        }
    }

    close(s);

    return 0;
}
In the client code, of course you'll notice that there are only a few system calls used to set things up: socket() and connect(). Since the client isn't going to be accept()ing any incoming connections, there's no need for it to listen(). Of course, the client still uses send() and recv() for transferring data. That about sums it up.

11.4. socketpair()—quick full-duplex pipes

What if you wanted a pipe(), but you wanted to use a single pipe to send and recieve data from both sides? Since pipes are unidirectional (with exceptions in SYSV), you can't do it! There is a solution, though: use a Unix domain socket, since they can handle bi-directional data.
What a pain, though! Setting up all that code with listen() and connect() and all that just to pass data both ways! But guess what! You don't have to!
That's right, there's a beauty of a system call known as socketpair() this is nice enough to return to you a pair of already connected sockets! No extra work is needed on your part; you can immediately use these socket descriptors for interprocess communication.
For instance, lets set up two processes. The first sends a char to the second, and the second changes the character to uppercase and returns it. Here is some simple code to do just that, called spair.c (with no error checking for clarity):
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

int main(void)
{
    int sv[2]; /* the pair of socket descriptors */
    char buf; /* for data exchange between processes */

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
        perror("socketpair");
        exit(1);
    }

    if (!fork()) {  /* child */
        read(sv[1], &buf, 1);
        printf("child: read '%c'\n", buf);
        buf = toupper(buf);  /* make it uppercase */
        write(sv[1], &buf, 1);
        printf("child: sent '%c'\n", buf);

    } else { /* parent */
        write(sv[0], "b", 1);
        printf("parent: sent 'b'\n");
        read(sv[0], &buf, 1);
        printf("parent: read '%c'\n", buf);
        wait(NULL); /* wait for child to die */
    }

    return 0;
}
Sure, it's an expensive way to change a character to uppercase, but it's the fact that you have simple communication going on here that really matters.
One more thing to notice is that socketpair() takes both a domain (AF_UNIX) and socket type (SOCK_STREAM). These can be any legal values at all, depending on which routines in the kernel you want to handle your code, and whether you want stream or datagram sockets. I chose AF_UNIX sockets because this is a Unix sockets document and they're a bit faster than AF_INET sockets, I hear.
Finally, you might be curious as to why I'm using write() and read() instead of send() and recv(). Well, in short, I was being lazy. See, by using these system calls, I don't have to enter the flags argument that send() and recv() use, and I always set it to zero anyway. Of course, socket descriptors are just file descriptors like any other, so they respond just fine to many file manipulation system calls.

Unix Domain Sockets?

"Unix Domain Sockets? "

The often overlooked Unix domain socket facility is one of the most powerful features in any modern Unix. Most socket programing books for Unix discus the topic mearly in an academic sense without ever explaining why it matters or what it is used for. Besides being the only way utilize certain abilities of the operating system, it is an area programers new to Linux, BSD, and other Unicies definitely need to be aware of. This is not a tutorial on sockets, rather a review of the features and benefits of one area of sockets programming.

Background and Context

The closest thing to a Unix domain socket would be a pipe. Unix pipes are an integral cornerstone of the OS at large. Analogous to a water pipe with water flowing in one direction, a stream of bytes flows from the write side of a pipe to the read side. A separate open file descriptor maintains a reference to the read and write side of a pipe. The different sides of the pipe can be in different processes or threads as long as they reside on the same local computer. Lets review the distinguishing characteristics of pipes in Unix.
  • Writes less than 4kb are atomic
  • Pipes can be created and inherited across a fork() call, as well as shared between threads.
  • Pipes can also be given a name in the file system. These fifos (or named pipes) exist beyond the lives of processes. Two different processes can obtain a reference to the pipe with open() as opposed to having to inherit a file descriptor.
  • Pipes are generally considered to be faster than Unix domain sockets.
  • Processes using pipes must still perform context switches with the kernel to use the read() and write() system calls.
As an exception to the fact that pipes must be written from one side and read from the other, Solaris pipes are full duplex. On Linux and BSD for example, full duplex operations with pipes use two different pipes. Named pipes and unnamed pipes are essentially the same thing. This is not the case with Windows. Windows provides two very different facilities, for what it calls named and anonymous pipes. Anonymous pipes are available in all versions of windows, and behave much like Unix pipes. Besides being dramatically slower, there are however several variations such as an adjustable pipe cache size that also effects the threshold for atomic writes. Windows named pipes are roughly analogous to Unix domain sockets. They are only available on the NT derived windows versions, and do not use the windows networking socket interface, winsock, at all. They do have the advantage of reaching across multiple computers in a NT domain.

On with It

A unix domain socket exists only inside a single computer. The word domain here has nothing to do with NIS, LDAP, or Windows, and instead refers to the file system. Unix domain sockets are identified by a file name in the file system like a named pipe would be. Programs communicating with a Unix domain socket must be on the same computer so they are not really a networking concept so much as they are an inter-process communication (IPC) concept. This explains why most networking books ignore them. They are interfaced with the same sockets API that is used for TCP/IP, UDP/IP, as well as other supported network protocols. You should be thinking at least two questions right now: "Why would a network program ever support Unix domain sockets as a transport?", and "Why would programs use a unix domain socket for an IPC mechanism instead of pipes, signals, or shared memory?". Here's some quick answers.
  • Unix domain sockets are secure in the network protocol sense of the word, because:
    • they cannot be eased dropped on by a sleezy network
    • remote computers cannot connect to them without some sort of forwarding mechanism
  • They do not require a properly configured network, or even network support at all
  • They are full duplex
  • Many clients can be connect to the same server using the same named socket
  • Both connectionless (datagram), and connection oriented (stream) communication is supported
  • Unix domain sockets are secure in the IPC sense of the word, because:
    • File permissions can be configured on the socket to limit access to certain users or groups
    • Because everything that is going on takes place on the same computer controlled by a single kernel, the kernel knows everything about the socket and the parties on both sides. This means, server programs that need authentication can find out what user is connecting to them without having to obtain a user name and password.
  • Open file descriptors from one process can be sent to another totally unrelated process
  • Parties can know what PID is on the other side of a Unix domain Socket
Not all of these features are available on every Unix. Worse there are variations on the way they are interfaced. Basic operations are pretty universally supported though. Lets move on to some examples.

Basic Connection-Oriented Client & Server

Lets start with a very basic client and a forking server. A forking server spawns a new process to handle each incoming connection. After a connection is closed, its handler process exits. This type of server frequently gets a bad reputation due to its poor performance as a web server. The reason it performs poorly as a web server is because with HTTP, every single request is made with its own connection. The server thus spends a relatively disproportional amount of time creating and destroying processes versus actually handling requests. What is not commonly understood is that for other types a protocols which maintain a single connection during the entire time the client uses the server, a forking server is considered an acceptable design. Take Open SSH for example. The primary problem with this design for non-web server applications is that it is no longer as strait forward to share information between all the various handler instances. Multiplexing and multi-threaded as well as all sorts of other designs are out there, but the simple forking() server is a good as it gets for illustrating examples. Think of it as the "hello world" of server designs. Take the following sources.
client1.c
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

int main(void)
{
 struct sockaddr_un address;
 int socket_fd, nbytes;
 size_t address_length;
 char buffer[256];

 socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
 if(socket_fd < 0)
 {
  printf("socket() failed\n");
  return 1;
 }
 
 address.sun_family = AF_UNIX;
 address_length = sizeof(address.sun_family) +
                  sprintf(address.sun_path, "./demo_socket");

 if(connect(socket_fd, (struct sockaddr *) &address, address_length) != 0)
 {
  printf("connect() failed\n");
  return 1;
 }

 nbytes = sprintf(buffer, "hello from a client");
 write(socket_fd, buffer, nbytes);
 
 nbytes = read(socket_fd, buffer, 256);
 buffer[nbytes] = 0;

 printf("MESSAGE FROM SERVER: %s\n", buffer);

 close(socket_fd);

 return 0;
}
server1.c
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <unistd.h>

int connection_handler(int connection_fd)
{
 int nbytes;
 char buffer[256];

 nbytes = read(socket_fd, buffer, 256);
 buffer[nbytes] = 0;

 printf("MESSAGE FROM CLIENT: %s\n", buffer);
 nbytes = sprintf(buffer, "hello from the server");
 write(socket_fd, buffer, nbytes);
 
 close(connection_fd);
 return 0;
}

int main(void)
{
 struct sockaddr_un address;
 int socket_fd, connection_fd;
 size_t address_length;
 pid_t child;
 
 socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
 if(socket_fd < 0)
 {
  printf("socket() failed\n");
  return 1;
 } 

 unlink("./demo_socket");
 address.sun_family = AF_UNIX;
 address_length = sizeof(address.sun_family) +
                  sprintf(address.sun_path, "./demo_socket");

 if(bind(socket_fd, (struct sockaddr *) &address, address_length) != 0)
 {
  printf("bind() failed\n");
  return 1;
 }

 if(listen(socket_fd, 5) != 0)
 {
  printf("listen() failed\n");
  return 1;
 }

 while((connection_fd = accept(socket_fd, 
                               (struct sockaddr *) &address,
                               &address_length)) > -1)
 {
  child = fork();
  if(child == 0)
  {
   /* now inside newly created connection handling process */
   return connection_handler(connection_fd);
  }

  /* still inside server process */
  close(connection_fd);
 }

 close(socket_fd);
 unlink("./demo_socket");
 return 0;
}
Armed with a some basic knowledge of C, beginner level Unix system programing, beginner level sockets programing, how to lookup man pages, and Google, the above example will help you create a UDS client and server. To try it out open a couple terminal windows, run the server in one, and the client in the other. After that try adding a something like sleep(15) to the server's connection handler, before it write()s back to the client. Bring up two more terminals, one with another instance of client and the other with top or ps -e, also netstat -au. Experiment with that for a while. Learn anything?
At this point there are several things we could do with this technology, that is: the ability to have running programs communicate with other arbitrary programs on the same computer. Taking into consideration were in the file system our socket is created and with what permissions, this could programs running with different credentials, that started at different times, or even with different login sessions (controlling ttys). A common example of a program that works like this is syslogd. On many unix types, programs use a unix domain socket to pass log messages to the syslog server.
There are other ways this could be accomplish without unix domain sockets, but not only are they pretty hard to beat, UDS allow for even more abilities.

An Authenticated Server

Let us imagine a database server like PostgreSQL. The server can force every client program that connects to it to authenticate itself with a user name and password. It does this so that it can enforce its internal security policies based on what account a client is connecting with. Having to authenticate with a user name / password pair every time can get old so often other authentication schemes such as key pair authentication are used alternatively. In the case of local logins (client is on the same machine as the server) a feature of unix domain sockets known as credentials passing can be used.
This is one area that is going to be different everywhere, so check your reference material. Let's look at how its done in Linux. Have a look here for how it's done on Open BSD.

The Real Sockets IO API

Those new and old to sockets programming are often unaware that the sockets API actually has its own IO routines: send(), sendto(), sendmsg(), recv(), recvfrom(), and recvmsg(). These functions operate on sockets, not file descriptors. Unix automatically creates a file descriptor for a socket when its created (with the same integer value) so that IO operations can be performed on the socket just as with normal file descriptors, that is with read(), write(), and the like. This is why most of the time the underlying socket IO functions don't need to be used directly. Certain features do require the use of the lower level functions (like UDP). This is also why in windows with winsock version 2 or greater (this is the version that internally uses the same open source BSD sockets code, unlike winsock 1) the same send/recv socket IO functions are available (all though not advertised). Also note that windows to, provides a way to use sockets as windows file HANDLES.
Linux uses a lower level socket function to grab the credentials of the process on the other side of unix domain socket, the multi-purpose getsockopt().
Credentials passing on Linux
struct ucred credentials;
 int ucred_length = sizeof(struct ucred);

 /*fill in the user data structure */
 if(getsockopt(connection_fd, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length))
 {
  printf("could obtain credentials from unix domain socket");
  return 1;
 }

 /* the process ID of the process on the other side of the socket */
 credentials.pid;

 /* the effective UID of the process on the other side of the socket  */
 credentials.uid;

 /* the effective primary GID of the process on the other side of the socket */
 credentials.gid;

 /* To get supplemental groups, we will have to look them up in our account
    database, after a reverse lookup on the UID to get the account name.
    We can take this opportunity to check to see if this is a legit account.
 */

File Descriptor Passing

File descriptors can be sent from one process to another by two means. One way is by inheritance, the other is by passing through a unix domain socket. There are three reasons I know of why one might do this. The first is that on platforms that don't have a credentials passing mechanism but do have a file descriptor passing mechanism, an authentication scheme based on file system privilege demonstration could be used instead. The second is if one process has file system privileges that the other does not. The third is scenarios where a server will hand a connection's file descriptor to another all ready started helper process of some kind. Again this area is different from OS to OS. On Linux this is done with a socket feature known as ancillary data.
It works by one side sending some data to the other (at least 1 byte) with attached ancillary data. Normally this feature is used for odd features of various underlying network protocols, such as TCP/IP's almost pointless out of band data. This is accomplished with the lower level socket function sendmsg() that accepts both arrays of IO vectors and control data message objects as members of its struct msghdr parameter. Ancillary, also known as control, data in sockets takes the form of a struct cmsghdr. The members of this structure can mean different things based on what type of socket it is used with. Making it even more squirrelly is that most of these structures need to be modified with macros. Here are two example functions based on the ones available in Warren Gay's book mention at the end of this article. A socket's peer that read data sent to it by send_fd() without using recv_fd() would just get a single capital F.

int send_fd(int socket, int fd_to_send)
 {
  struct msghdr message;
  struct iovec iov[1];
  struct cmsghdr *control_message = NULL;
  char buffer[CMSG_SPACE(int)], data[1];


  memset(&message, 9, sizeof(struct msghdr));
  memset(buffer, CMSG_SPACE(int));

  data[0] = 'F';
  iov[0].iov_base = data;
  iov[0].iov_len = 1;

  message.msg_iov = iov;
  message.msg_iovlen = 1;

  control_message = CMSG_FIRSTHDR(&message);
  control_message->cmsg_level = SOL_SOCKET;
  control_message->cmsg_type = SCM_RIGHTS;
  control_message->cmsg_len= CMSG_LEN(sizeof int);

  *((int *) CSM_DATA(cmsgp)) = fd_to_send;

  message.msg_controllen = control_message->cmsg_legn;

  return sendmsg(socket, &message, 0);
 }
int recv_fd(int socket)
 {
  int sent_fd;
  struct msghdr message;
  struct iovec iov[1];
  struct cmsghdr *control_message = NULL;
  char buffer[CMSG_SPACE(sizeof fd)], data[1];

  memset(&message, 9, sizeof(struct msghdr));
  memset(buffer, CMSG_SPACE(int));

  message.msg_iov = iov;
  message.msg_iovlen = 1;

  message.msg_control = buffer;
  message.msg_controllen = sizeof(CMSG_SPACE(int));

  if(recvmsg(s, &message, 0) < 0)
   return -1;

  for(control_message = CMSG_FIRSTHDR(&message);
      control_message != NULL;
      control_message = CMSG_NXTHDR(&messsage,
                                    control_message))
  {
   if( (control_message->cmsg_level == SOL_SOCKET) &&
       (control_message->cmsg_type == SCM_RIGHTS) )
   {
    return *((int *) CMSG_DATA(control_message);
   }
  }

  return -1;
 }

Datagram Unix Domain Sockets

Most of the time programs that communicate over a network work with stream, or connection oriented technology. This is when an additional software layer such as TCP's Nagle algorithm creates a virtual communication circuit out of the many single atomic (stateless) packets used by a underlying packet switched network. Sometimes we want to instead simply work with individual packets, such is the case with UDP. This technology is often called datagram communication. This strategy allows for a variety of trade-offs. One is the ability to make a low overhead, high performance server with a single context or "main loop" that handles multiple simultaneous clients. Although unix domain sockets are not a network protocol they do utilize the sockets network interface, and as such also provide datagram features.
Datagram communication works best with an application that can put a complete atomic message of some sort in a single packet. This can be a problem for UDP as various setbacks can limit the size of a packet to as little as 512 bytes. The limit for datagrams over a unix domain socket is much higher. A complete example is beyond our scope for this article. Those interested should find a UDP example (much easier to find) and combine that with the techniques above.

Abstract Names

Another Linux specific feature is abstract names for unix domain sockets. Abstract named sockets are identical to regular UDS except that their name does not exist in the file system. This means two things: file permissions do not apply, and they can be accessed from inside chroot() jails. The trick is to make the first byte of the address name null. Look at the output from netstat -au to see what it looks while one of these abstract named sockets is in use. Example:
setting the first byte to null
address.sun_family = AF_UNIX;
 address_length = sizeof(address.sun_family) +
                  sprintf(address.sun_path, "#demo_socket");
 
 address.sun_path[0] = 0;

 bind(socket_fd, (struct sockaddr *) &address, address_length);

Conclusion

Even if you never need to directly program UD sockets, they are an important facet of understanding both the Unix security model and the inter-workings of the operating system. For those that do use them, they open up a world of possibilities.

A UNIX Domain Sockets

UNIX domain sockets are named with UNIX paths. For example, a socket might be named /tmp/foo. UNIX domain sockets communicate only between processes on a single host. Sockets in the UNIX domain are not considered part of the network protocols because they can be used to communicate only between processes on a single host.
Socket types define the communication properties visible to a user. The Internet domain sockets provide access to the TCP/IP transport protocols. The Internet domain is identified by the value AF_INET. Sockets exchange data only with sockets in the same domain.

Creating Sockets

The socket(3SOCKET) call creates a socket in the specified family and of the specified type.
s = socket(family, type, protocol);
If the protocol is unspecified (a value of 0), the system selects a protocol that supports the requested socket type. The socket handle (a file descriptor) is returned.
The family is specified by one of the constants defined in sys/socket.h. Constants named AF_suite specify the address format to use in interpreting names.
The following creates a datagram socket for intramachine use:
s = socket(AF_UNIX, SOCK_DGRAM, 0);
Set the protocol argument to 0, the default protocol, in most situations.

Local Name Binding

A socket is created with no name. A remote process has no way to refer to a socket until an address is bound to the socket. Communicating processes are connected through addresses. In the UNIX family, a connection is composed of (usually) one or two path names. UNIX family sockets need not always be bound to a name. If they are, bound, duplicate ordered sets such as local pathname or foreign pathname can never exist. The path names cannot refer to existing files.
The bind(3SOCKET) call enables a process to specify the local address of the socket. This creates the local pathname ordered set, while connect(3SOCKET) and accept(3SOCKET) complete a socket's association by fixing the remote half of the address. Use bind(3SOCKET) as follows:
bind (s, name, namelen);
The socket handle is s. The bound name is a byte string that is interpreted by the supporting protocols. UNIX family names contain a path name and a family. The example shows binding the name /tmp/foo to a UNIX family socket.
#include <sys/un.h>
 ...
struct sockaddr_un addr;
 ...
strcpy(addr.sun_path, "/tmp/foo");
addr.sun_family = AF_UNIX;
bind (s, (struct sockaddr *) &addr,
  strlen(addr.sun_path) + sizeof (addr.sun_family));
When determining the size of an AF_UNIX socket address, null bytes are not counted, which is why you can use strlen(3C).
The file name referred to in addr.sun_path is created as a socket in the system file name space. The caller must have write permission in the directory where addr.sun_path is created. The file should be deleted by the caller when it is no longer needed. Delete AF_UNIX sockets with unlink(1M).

Establishing a Connection

Connection establishment is usually asymmetric. One process acts as the client and the other as the server. The server binds a socket to a well-known address associated with the service and blocks on its socket for a connect request. An unrelated process can then connect to the server. The client requests services from the server by initiating a connection to the server's socket. On the client side, the connect(3SOCKET) call initiates a connection. In the UNIX family, this might appear as:
struct sockaddr_un server;
  server.sun.family = AF_UNIX;
   ...
  connect(s, (struct sockaddr *)&server, strlen(server.sun_path) 
         + sizeof (server.sun_family));
 

UNIX Domain Sockets

UNIX domain sockets are used to communicate with processes running on the same machine. Although Internet domain sockets can be used for this same purpose, UNIX domain sockets are more efficient. UNIX domain sockets only copy data; they have no protocol processing to perform, no network headers to add or remove, no checksums to calculate, no sequence numbers to generate, and no acknowledgements to send.
UNIX domain sockets provide both stream and datagram interfaces. The UNIX domain datagram service is reliable, however. Messages are neither lost nor delivered out of order. UNIX domain sockets are like a cross between sockets and pipes. You can use the network-oriented socket interfaces with them, or you can use the socketpair function to create a pair of unnamed, connected, UNIX domain sockets.

#include <sys/socket.h>

int socketpair(int domain, int type, int protocol,
 int sockfd[2]);

Returns: 0 if OK, 1 on error

Although the interface is sufficiently general to allow socketpair to be used with arbitrary domains, operating systems typically provide support only for the UNIX domain.

Examples_pipe Function Using UNIX Domain Sockets
Figure 17.13 shows the socket-based version of the s_pipe function previously shown in Figure 17.6. The function creates a pair of connected UNIX domain stream sockets.
Some BSD-based systems use UNIX domain sockets to implement pipes. But when pipe is called, the write end of the first descriptor and the read end of the second descriptor are both closed. To get a full-duplex pipe, we must call socketpair directly.

Figure 17.13. Socket version of the s_pipe function
#include "apue.h" #include <sys/socket.h> /* * Returns a full-duplex "stream" pipe (a UNIX domain socket) * with the two file descriptors returned in fd[0] and fd[1]. */ int s_pipe(int fd[2]) { return(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)); }

17.3.1. Naming UNIX Domain Sockets

Although the socketpair function creates sockets that are connected to each other, the individual sockets don't have names. This means that they can't be addressed by unrelated processes.
In Section 16.3.4, we learned how to bind an address to an Internet domain socket. Just as with Internet domain sockets, UNIX domain sockets can be named and used to advertise services. The address format used with UNIX domain sockets differs from Internet domain sockets, however.
Recall from Section 16.3 that socket address formats differ from one implementation to the next. An address for a UNIX domain socket is represented by a sockaddr_un structure. On Linux 2.4.22 and Solaris 9, the sockaddr_un structure is defined in the header <sys/un.h> as follows:
struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[108]; /* pathname */ };
On FreeBSD 5.2.1 and Mac OS X 10.3, however, the sockaddr_un structure is defined as
struct sockaddr_un { unsigned char sun_len; /* length including null */ sa_family_t sun_family; /* AF_UNIX */ char sun_path[104]; /* pathname */ };
The sun_path member of the sockaddr_un structure contains a pathname. When we bind an address to a UNIX domain socket, the system creates a file of type S_IFSOCK with the same name.
This file exists only as a means of advertising the socket name to clients. The file can't be opened or otherwise used for communication by applications.
If the file already exists when we try to bind the same address, the bind request will fail. When we close the socket, this file is not automatically removed, so we need to make sure that we unlink it before our application exits.

Example
The program in Figure 17.14 shows an example of binding an address to a UNIX domain socket.
When we run this program, the bind request succeeds, but if we run the program a second time, we get an error, because the file already exists. The program won't succeed again until we remove the file.
$ ./a.out run the program UNIX domain socket bound $ ls -l foo.socket look at the socket file srwxrwxr-x 1 sar 0 Aug 22 12:43 foo.socket $ ./a.out try to run the program again bind failed: Address already in use $ rm foo.socket remove the socket file $ ./a.out run the program a third time UNIX domain socket bound now it succeeds
The way we determine the size of the address to bind is to determine the offset of the sun_path member in the sockaddr_un structure and add to this the length of the pathname, not including the terminating null byte. Since implementations vary in what members precede sun_path in the sockaddr_un structure, we use the offsetof macro from <stddef.h> (included by apue.h) to calculate the offset of the sun_path member from the start of the structure. If you look in <stddef.h>, you'll see a definition similar to the following:
#define offsetof(TYPE, MEMBER) ((int)&((TYPE *)0)->MEMBER)
The expression evaluates to an integer, which is the starting address of the member, assuming that the structure begins at address 0.


Unique Connections
A server can arrange for unique UNIX domain connections to clients using the standard bind, listen, and accept functions. Clients use connect to contact the server; after the connect request is accepted by the server, a unique connection exists between the client and the server..
First, we create a single UNIX domain socket by calling socket. We then fill in a sockaddr_un structure with the well-known pathname to be assigned to the socket. This structure is the argument to bind. Note that we don't need to set the sun_len field present on some platforms, because the operating system sets this for us using the address length we pass to the bind function.
Finally, we call listen (Section 16.4) to tell the kernel that the process will be acting as a server awaiting connections from clients. When a connect request from a client arrives, the server calls the serv_accept function.
The server blocks in the call to accept, waiting for a client to call cli_conn. When accept returns, its return value is a brand new descriptor that is connected to the client. (This is somewhat similar to what the connld module does with the STREAMS subsystem.) Additionally, the pathname that the client assigned to its socket (the name that contained the client's process ID) is also returned by accept, through the second argument (the pointer to the sockaddr_un structure). We null terminate this pathname and call stat. This lets us verify that the pathname is indeed a socket and that the permissions allow only user-read, user-write, and user-execute. We also verify that the three times associated with the socket are no older than 30 seconds. (Recall from Section 6.10 that the time function returns the current time and date in seconds past the Epoch.)
If all these checks are OK, we assume that the identity of the client (its effective user ID) is the owner of the socket. Although this check isn't perfect, it's the best we can do with current systems. (It would be better if the kernel returned the effective user ID to accept as the I_RECVFD ioctl command does.)
The client initiates the connection to the server by calling the cli_conn function.

Multiplexing filehandles with select() in perl.


The problem

I/O requests such as read() and write() are blocking requests. Suppose you have a line in a program that get STDIN from a terminal like the following: $input = <STDIN>; What will happen here is that the program's execution will block until there a line of input is available, i.e. the user types something followed by a newline. In many cases this is the desired behavior. Suppose you have a program that accepts requests through a socket and does some processing for each request, then moves on to the next request.
01 # Create the receiving socket
02 my $s = new IO::Socket ( 
03 LocalHost => thekla, 
04 LocalPort => 7070, 
05 Proto => 'tcp' 
06 Listen => 16, 
07 Reuse => 1, 
08 ); 
09 die "Could not create socket: $!\n" unless $s; 
10 
11 my ($ns, $buf); 
12 while( $ns = $s->accept() ) { # wait for and accept a connection 
13 while( defined( $buf = <$ns> ) ) { # read from the socket 
14 # do some processing 
15 } 
16 } 
17 close($s); Although this is a perfectly valid way of handling the incoming requests, it does suffer some serious problems, especially if the frequency of incoming requests is high and the processing that needs to be performed for each is a lot. Clearly, the problem is that, once a request has been accepted, we have to keep other requests hanging in the queue while we read the request message and process it. Now, reading from a socket is a blocking call, so if the client takes too long to transmit the request message, we just sit there waiting while we could be doing useful processing of other requests. Obviously, not only this is not acceptable, but in cases where the demand for request processing is high, the program may not be able to meet its operating reqiurements. Also think that a single client failure at a critical point (in the middle of an ongoing transmission) poses the risk of making the server block indefinetly.

What can we do about it?

What we need to deal with situations like the above, is a way to handle I/O (we use sockets for this example, but the rules apply in general to any kind of filehandles) independently and with some sort of apparent parallelism/multiprocessing. There are two very common approaches to deal with this. One approach is to spawn separate threads of control to handle each request. This can be done either at process-level, using fork() to create a new process for each request, or at thread-level using perl's threading capabilities to create multiple threads within the same process. (Perl's support for threads was introduced in version 5.005) The other approach - which is the one that we will discuss here - is to use the select() to multiplex between several filehandles within a single thread of control, thus creating the effect of parallelism in the handling of I/O.

What does select() do?

The idea behind select() is to avoid blocking calls by making sure that a call will not block before attempting it. How do we do that? Suppose we have two filehandles, and we want to read data from them as it comes in. Let's call them A and B. Now, let's assume that A has no input pending yet, but B is ready to respond to a read() call. If we know this bit of information, we can try readin from B first, instead of A, knowing that our call will not block. select() gives us this bit of information. All we need to do is to define sets of filehandles (one for reading, one for writing and one for errors) and ask call select() on them which will return a filehandle which is ready to perform the operation for which it has been delegated (depending on which set it is in) as soon as such a filhandle is ready. Obviously this provides us with the advantage of always picking up a filehandle that will not block thus avoiding the possibility of delaying the entire program for one lazy filehandle just because it happened to be the first we picked at random. Still, it does not guarantee that the selected filehandle is the best choice, because we still don't know how much data can be read, or how qucikly it can take in data that we wrte to it. But it is definetly a big step forward from our initial program.

Using select()

We will try writing the example program we attempted on the beginnign of this article, but now using the select() method. Instead of using perl's select call directly we will use a wrapper module, IO::Select that makes life easier for us.
... create socket as before ... 
11 use IO::Select; 
12 $read_set = new IO::Select(); # create handle set for reading 
13 $read_set->add($s); # add the main socket to the set 
14 
15 while (1) { # forever 
16 # get a set of readable handles (blocks until at least one handle is ready) 
17 my ($rh_set) = IO::Select->select($read_set, undef, undef, 0); 
18 # take all readable handles in turn 
19 foreach $rh (@$rh_set) { 
20 # if it is the main socket then we have an incoming connection and 
21 # we should accept() it and then add the new socket to the $read_set 
22 if ($rh == $s) {
23 $ns = $rh->accept(); 
24 $read_set->add($ns); 
25 } 
26 # otherwise it is an ordinary socket and we should read and process the request 
27 else { 
28 $buf = <$rh>; 
29 if($buf) { # we get normal input 
30 # ... process $buf ... 
31 } 
32 else { # the client has closed the socket 
33 # remove the socket from the $read_set and close it
34 $read_set->remove($rh); 
35 close($rh);
36 } 
37 } 
38 } 
39 }
We create an IO::Select object, $read_set, which is our set of handles to test for readability, and add all open handles to it. We start by adding the main socket and each time a new connection is made returning a new socket for it, we add that socket to the set. Then we go into a loop where we ask select to give us a list of readable handles and we examine each one in turn. If it is the main socket then we want to call accept() to receive the incoming connection and add the new socket to the read set. Otherwise it must be an ordinary socket in which case we read from it and process its input. If the read fails, that means the socket has been closed on the client side, so we close it, too, and remove it from the read set. So we work our way continuously through the incoming requests, by making sure that a call for I/O on any filehandle will progress since select() tells us it will. As we already mentioned earlier, this method does not guarantee progress as it only tests whether a handle is ready to respond to I/O. The question still remains, whether the handle we pick from the ready ones is the one that will respond faster to I/O, and how much data there is available for reading or how much data it is ready to receive. So it is still possible to block a bit after the point where we picked the handle. Also, we did not take into account the impact on performance that the actual processing of requests will have. We might just be printing incoming data to a file, but then again, each request might need heavy processing that would slow down the entire handle processing loop. But these are issues that must be considered in the context of the individual application.

What’s your IP Address?

What’s your IP Address?

All computer’s connected to the internet/ any network for that matter have a unique address with which they are identified on that network. This unique address is your Internet Protocol Address or IP Address. In this post, i shall describe the process of identifying your IP Address.
To know your IP Address follow the steps below
  • Click on Start and Type CMD at Run.
  • Enter IPCONFIG at the CMD prompt. This displays you the IP Related information specific to your Home/ ISP network.
However, if you are on a home/ office network, the information you obtained just now is not the real IP address… that means, this is not the IP Address with which the outside world identifies you, rather, this is the address with which your home/office network identifies you . In order to figure out the IP Address with which the outside world ( i.e. the world on internet) identifies you, visit the website www.ipaddressworld.com or http://whatismyipaddress.com/ . These websites can help you identify your IP Address.
Whatismyipaddress
Do note that this is the IP Address of the computer connecting to the internet. In case of home networks, it is the IP Address of the proxy server.

Understanding IPv6


Every device on the network uses an address to with another device on another network. This address in layman terms is called an “IP Address”. The current scheme of IP Address assignment is called IPv4 or IP version 4 uses 32 bit number. This 32 bit number is usually represented by 4 numbers separated by periods. For example, 202.144.79.8 is an example of an IP address. IPv4 addressing scheme can at max represent upto 4 billion IP addresses. In order to figure out your IP Address, read What’s your IP Address?
A 32 bit number can represent up to 4 billion different IP addresses. In reality the number is somewhat less, since some numbers and digits have reserved meanings. Now from a practical standpoint, it turns out that4 billion isn’t enough. If you are wondering as to why 4 Billion is not enough, its so because of the way that IP addresses are assigned and used, we would be running out of new addresses in a few years from now. However, the good news is that we already have a solution for this. 
Internet Protocol Version 6, or IPv6 brings with it a lot of interesting features, however the most notable one is that IPv6 address is going to be 128 bits long instead of the conventional 32 bits. Though, it sounds like just a 4 time multiple of 32, the reality is somewhat different. 128 bit addresses in turn refers to 2128 (about 3.4×1038) addresses, which in turn seems like more than enough to give an IP address to every grain of sand on this earth . Picture the fact below which gives a number to the IP Addresses possible with the two different schemes and you can get a better idea.
To get a better idea, about the number of IP Addresses here is the exact number of addresses availbale with IPv4 and IPv6
IPv4: 4,294,967,296 addresses.
IPv6: 340,282,366,920,938,463,463,374,607,431,768,211,456 addresses.
The extended address length provided by IPv6 eliminates the need to use network address translation to avoid address exhaustion, further; it also simplifies aspects of address assignment and renumbering when changing Internet connectivity providers.
IPv6 addresses look something like 2001:0db8:3c4d:0015:0000:0000:abcd:ef12 .
This definitely seems like a tough thing to remember as opposed to the IPv4 address schemes, but the good news is that some kind of shorthand notation for this is also in the roadmap and maybe it wont be too tough to remember the IPv6 address as well.
Image: IPv6 Header
Image: IPv6 Header
Some Interesting changes and advantages which will come over to the Internet Addressing space with the adoption of IPv6 are:
1.) Larger Address Space: As I already wrote earlier, IPv6 will bring with it a very large address space of 2128 (about 3.4×1038) addresses.
2.) Multicasting vs. Broadcasting: IPv4 currently defines broadcast addresses for network address operation; with IPv6 there would be no need to define the broadcast address. Instead, IPv6 accomplishes broadcasting with a new implementation of multicast addressing that does not disturb all interfaces on a link.
3.) TTL field: In IPv6, the TTL field has been replaced by a Hop-Limit field. In a usual IPv4 scenario, TTL field gives the number of router hops covered. This data can be interpreted from a Ping request. Below is a sample response obtained from a ping request to www.google.com
Reply from 216.239.61.104: bytes=32 time=66ms TTL=240
Every time, a router is crossed; the value of TTL generally gets reduced by 1. In this scenario, the start value of the router would have been 256.
4.) Payload Size: Currently used IPv4 limits packets to 64  Kb ( 1Kb = 1024 bytes). IPv6 on the other hand has optional support for packets over this limit, which can be as large as 4 GB. This will result in more efficient usage of broadband.
5.) IPv6 allows for many new possibilities, including a new geolocation system that lines up IPv6 addresses with squares or hexagons across the earth’s surface, in a new and novel latitude and longitude system that can be scaled down to nearly microscopic granularity.
6.) Resource Allocation support in IPv6 : IPv6 provides a mechanism called Flow Label for resource allocation. Flow label enables source to send request for the special handling of a packet. This mechanism is really helpful in real-time audio and video transmission.
7.) Better header format : The header of IPv6 has been designed in a way to speed-up the routing process. In header of IPv6 options are separated from the base header. Options are inserted into base header only when required by the upper-layer data.
Interestingly, IPv6 might also bring in opportunities for cost savings for some hugely networked companies as there won’t be any need to dedicate a box to act as a DHCP server and a NAT, which in turn means that those servers can be utilized for other tasks.
Many people would have also heard of the term IPv5, but interestingly, it was not a successor to IPv4; rather, it was an experimental streaming protocol, intended to support voice, video, and audio.
The adoption of IPv6 is in progress and it might take us a few more years before we see the entire network space getting ruled by the IPv6. For those of you who still use IPv4 and have no roadmap for transitioning from v4 to v6, maybe someday you will be forced to switch but then it’s pretty transparent, and you probably won’t be affected for some time. There actually is some IPv6 traffic on the internet already, using techniques to coexist with the IPv4 traffic.
As far as the migration of traffic from IPv4 to IPv6 is concerned, it will happen over time. Internet today is more like a cloud of heavy density IPv4 addresses. Slowly over the time, when IPv6 address space will start building up; IPv4 cloud will start shrinking.
The approach that most organizations will most probably take to adopting IPv6 is to running it natively on their backbones. Most of the organizations will then be using IPv6 over IPv4 tunneling for connectivity between the backbone and IPv4 nodes on their own networks, as well as Internet traffic exchange with the outside world. Though, this approach seems like an ideal migration strategy. It has its drawbacks as well; tunneling can slow throughput and it also requires network managers to configure information about tunnel endpoints into the encapsulating node, which is a time-consuming process.
There are certainly other migration approaches available as well. One of the other most widely known and discussed strategy is called ‘6over4’. This can be used if a multicast is available for IPv4. In this strategy a IPv6 multicast will be deployed over a IPv4 multicast. IPv6 can then utilize neighbor discovery for self-configuration.