1

I was trying to do a simple tcp server client using ipv6. It works on the same machine for ipv6 and ipv4 but when on different machines ipv6 fails to connect.

Server Code

int main(int argc, char* argv[])
{
    int sockfd,new_fd,rv,yes=1; 
    struct addrinfo hints,*servinfo,*p; 
    struct sockaddr_storage their_addr;
    socklen_t addr_size;

    SOCKET listenSocket,clientSocket;
    WSADATA w;

    if (WSAStartup(0x0101, &w) != 0)
    {
        fprintf(stderr, "Could not open Windows connection.\n");
        exit(0);
    }

    //ip=argv[1];
    //port=argv[2];

    memset(&hints,0,sizeof(hints));

    hints.ai_family=AF_INET6;
    hints.ai_socktype=SOCK_STREAM;  
    hints.ai_flags=AI_NUMERICHOST;

    if((rv = getaddrinfo("fe80::c0a8:0160","5002",&hints,&servinfo)) != 0)
    {
        perror("\nGetaddrinfo failed\n");
        return 1;
    }   

    //Creating socket   
    listenSocket = socket(servinfo->ai_family,servinfo->ai_socktype,servinfo->ai_protocol);

    if(listenSocket == INVALID_SOCKET)
    {
        printf("\nSocket failed with error \n");
        WSACleanup();
    }

    //setting non blocking mode
    u_long iMode = 1;
    rv = ioctlsocket(listenSocket,FIONBIO,&iMode);

    if(rv == SOCKET_ERROR)
    {
        printf("\nioctl failed\n");
        WSACleanup();
    }

    rv = bind(listenSocket,servinfo->ai_addr,(int)servinfo->ai_addrlen);

    if(rv == SOCKET_ERROR)
    {
        perror("\nBind: \n");
    }

    freeaddrinfo(servinfo);

    rv = listen(listenSocket,SOMAXCONN);

    if(rv == SOCKET_ERROR)
    {
        perror("listen");
        return 1;
    }

    // now accept an incoming connection:


    char recvbuf[DEFAULT_BUFLEN];
    int buflen = DEFAULT_BUFLEN;
    SOCKET AcceptSocket;

    while (1)
    {
        AcceptSocket = SOCKET_ERROR;

        while (AcceptSocket == SOCKET_ERROR)
        {
            AcceptSocket = accept(listenSocket, NULL, NULL);
        }

        printf("Server: Client Connected!\n");
        listenSocket = AcceptSocket;

        rv = recv(listenSocket,recvbuf,buflen,0);
        break;
    }


    printf("Received %d bytes from client \n",rv);  

    closesocket(listenSocket);
    closesocket(AcceptSocket);

    return 0;

}

Client Code

int main(int argc,char* argv[])
{
    struct addrinfo hints,*servinfo,*p;
    int rv;
    SOCKET connectSocket;
    WSADATA w;

    if (WSAStartup(0x0101, &w) != 0)
    {
        fprintf(stderr, "Could not open Windows connection.\n");
        exit(0);
    }

    //resetting memory
    memset(&hints,0,sizeof(hints));

    hints.ai_family = AF_INET6;
    hints.ai_socktype = SOCK_STREAM;    
    hints.ai_flags = AI_NUMERICHOST;

    //getting values

    if((rv = getaddrinfo("fe80::c0a8:160","5002",&hints,&servinfo)) != 0)
    {
        perror("Getaddrinfo failed");
        return 1;
    }

    //Creating socket
    connectSocket = socket(servinfo->ai_family,servinfo->ai_socktype,servinfo->ai_protocol);

    if(connectSocket == INVALID_SOCKET)
    {
        perror("Socket create : ");
    }

    rv = connect(connectSocket,servinfo->ai_addr,(int)servinfo->ai_addrlen);
    if(rv == SOCKET_ERROR)
    {
        perror("Socket Connect : ");
    }


    //free memory
    freeaddrinfo(servinfo);


    // Send and receive data.
    int bytesSent;

    char sendbuf[200] = "Client: Sending some test string to server...";
    char recvbuf[200] = "";

    bytesSent = send(connectSocket, sendbuf, strlen(sendbuf), 0);
    printf("Client: send() - Bytes Sent: %ld\n", bytesSent);

    closesocket(connectSocket);
    return 0;
}

The aim is just to print how many bytes transferred.

Antarus
  • 1,573
  • 2
  • 15
  • 32
  • As answered by shinkou you bind to a link-local address. The other problem is that you bind to a static address, which works on the computer which _has_ that address, but won't work on any computer which doesn't have this exact address. I recommend bind to `IN6ADDR_ANY_INIT` which binds to all interfaces so the server can be connected on all addresses the computer has. – Some programmer dude Nov 08 '12 at 06:48
  • @JoachimPileborg i've assigned a static ipv6 to the machine. Also Pinging between the 2 machines is working fine. – Antarus Nov 08 '12 at 07:07
  • And you changed the address in the code when you moved it to the other machine? Or do _both_ machines have the same address? – Some programmer dude Nov 08 '12 at 07:11
  • @JoachimPileborg both wer assigned different addresses and i'd changed it in the code as well . :) – Antarus Nov 08 '12 at 10:02

1 Answers1

3

It appears that you're using a link local address. Are you sure for that? Also, I'd suggest you check your firewall settings first.

EDIT: Try to include the zone ID. When you issue the ipconfig in command prompt, you should be able to get addresses like fe80::c0a8:0160%21 where %21 is the zone ID. It's important when you use link local addresses according to this answer.

Community
  • 1
  • 1
shinkou
  • 5,138
  • 1
  • 22
  • 32
  • No it is not link local address. I'd assigned manually the above used ip address. in fact i assigned a converted static ipv4. Firewall is enabled for home network and disabled for public networks. The machines used are in the same local network. – Antarus Nov 08 '12 at 07:05
  • Yes, it is a link local address. Every address that starts with fe80: is link local. For testing like this you can use addresses you get from your ISP or you can use ULA (http://www.sixxs.net/tools/grh/ula/) addresses. If you really want to use link local addresses you must explicitly specify the interface you want to use them on. They are link local after all :) – Sander Steffann Nov 08 '12 at 08:21
  • @Kols It is a link local address, but since both machines reside in the same network segment, it should work. – shinkou Nov 08 '12 at 08:22
  • @SanderSteffann i thot link local was the one which gets automatically set for eth0. for Example fe80::b8e1:d4bb:cbe4:f764%10 . Currently my ISP does not support ipv6. but my aim is just to connect between 2 machines in same network which will be assigned ipv6 addresses (statically). i've to check whether it'll work with autogenerated ipv6 (which has specified interface). Still that wasn't the thing i was looking for. :) shinkou i'll recheck for any ipv6 compatibility issue for the machines. – Antarus Nov 08 '12 at 10:04
  • Well it dint work with autogenerated ipv6 (which has specified interface) as well. Will there be any issues concerning tcp? because ping uses icmp packets right ? – Antarus Nov 09 '12 at 04:34
  • @Kols When you try to connect the client to the server, how does it fail? More specifically, what does the error message say? Does it pop up instantaneously? Or does it prompt for a few seconds before any error comes up? Also, how about if you use IPv4 addresses? Does it connect without problem? – shinkou Nov 09 '12 at 04:53
  • It works fine with ip4(AF_INET6 changed to AF_INET) . In ipv6 it fails with a timeout (10060) . – Antarus Nov 09 '12 at 08:46
  • *everything* that starts with `fe80:` is link-local. Please use normal addresses like ULA, otherwise it won't work the way you want it to. – Sander Steffann Nov 10 '12 at 11:07
  • @Kols I've edited my answer. Please take a look. If it doesn't work out, please let me know. – shinkou Nov 12 '12 at 02:30
  • it dint work between two machines after adding zone id . but it did work on the same machine. – Antarus Nov 12 '12 at 12:55
  • @SanderSteffann did you mean the ones starting with fd00:: ? And that too statically assigned ? – Antarus Nov 12 '12 at 12:56
  • 1
    @Kols It sounds like a firewall thing to me. Have you tried disabling firewall settings, not on the router, but on the machines? – shinkou Nov 12 '12 at 14:38
  • Yes, ULA addresses are the ones starting with `fd` (everything starting with `fd00:` to `fdff:`). A good way to generate an ULA prefix is with sixxs.net/tools/grh/ula. That will give you a /48 prefix. You can then take a /64 prefix from that for your LAN. How you configure it (static, SLAAC, stateful DHCPv6) does not matter that much. For your test environment static configuration is probably easiest. – Sander Steffann Nov 12 '12 at 15:43
  • @shinkou Yes. There was another firewall over the windows firewall in my system. I checked out the details, It was blocking ipv6 packets!! http://www.symantec.com/business/support/index?page=content&id=TECH180569 – Antarus Nov 14 '13 at 06:36
  • @SanderSteffann I tried to create a tunnel with sixxs.net but the tic server just hard blocked me. I dint do any automated scripts though. Anyway Hurricane Electric worked much easier for me. Still I have to disable my firewall for the tunnel to work. Since my firewall restricts ipv6 packets. :( Thanks a lot for your help. I understand that you are a pioneer in the world of ipv6. :) Taking my baby steps towards ipv6 world. – Antarus Nov 14 '13 at 06:40