简体   繁体   中英

Cannot connect to IPv6 address if its not ::1 in C

I'd like to connect to a ssh server which has an ipv6 address with libssh2.

It works but when I give an ip that isn't the localhost it fails to connect. The ip is correct because I can connect to it with ssh <ipv6> -p 22 .

const char *ip = "::1";

struct sockaddr_storage storage;
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &storage;
addr6->sin6_family = AF_INET6;
addr6->sin6_port = htons(22);
int sock;

if(inet_pton(AF_INET6, ip, &addr6->sin6_addr) == 1)
{
  if((sock = socket(AF_INET6, SOCK_STREAM, 0)) != -1)
  {
    if(connect(sock, (struct sockaddr *)(&storage), 
                     sizeof(struct sockaddr_in6)) == 0)
    {
      printf("works\n");
    }

    close(sock);
   }
}

Edit:

The suggestion ( memset(&storage, 0, sizeof(storage)) ) by @idz seems to have resolved the problem.

Non-static structures in C are not zero-initialized, so to avoid the possibility of garbage in the memory causing errors, you should zero them out.

Adding:

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

just after the storage declaration will do the trick.

While not directly related to the OP's error, it's always easier to find out what's going wrong if you do not throw away the error information available to you.

Exactly how you do this will depend on the environment you're coding in, but for a simple command line program you might do something like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// https://stackoverflow.com/questions/70157711/cannot-connect-to-ipv6-address-if-its-not-1-in-c

int main(int argc, const char * argv[]) {
    const char *ip = "::1";
    
    struct sockaddr_storage storage;
    memset(&storage, 0, sizeof(storage));
    struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &storage;
    addr6->sin6_family = AF_INET6;
    addr6->sin6_port = htons(22);
    
    int result = inet_pton(AF_INET6, ip, &addr6->sin6_addr);
    if (result != 1) {
        perror("inet_pton");
        exit(EXIT_FAILURE);
    }
    
    int sock = socket(AF_INET6, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }
    
    result = connect(sock, (struct sockaddr *)(&storage), sizeof(struct sockaddr_in6));
    if (result != 0) {
        perror("connect");
        exit(EXIT_FAILURE);
    }
    
    printf("It worked...\n");
    close(sock);
    return EXIT_SUCCESS;
}

In the case of garbage in the address this would report:

connect: Invalid argument

whereas a network routing issue would result in:

connect: No route to host

This makes it much easier to figure out what is going on!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM