0

Background: I'm following Beej's Guide to Network Programming on how to listen for and accept incoming connections using C sockets.

Problem: The problem I'm having is I'm getting segmentation faults when traversing the linked list of addresses to listen on. I do check if the next struct is null, but that isn't working.

What I've Tried: Between this code and previous working examples I've written, I can tell only one difference which is that these are addresses on my own computer vs another host. I've looked at the man pages for getaddrinfo too, and I'm following the example implementation as far as I can tell.

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>

#define MYPORT "6161"

int main() {
    struct addrinfo hints, *res;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_family = AI_PASSIVE;

    getaddrinfo(NULL, MYPORT, &hints, &res);

    struct addrinfo *addr;
    for (addr = res; addr != NULL; addr = addr->ai_next) {
        printf("Here's one addr!");
    }

    return 0;
}
Dylan Landry
  • 1,150
  • 11
  • 27
  • 1
    The only thing that comes up to my mind at first sight is that `getaddrinfo` might fail (I cannot figure out why though), thus not changing `res`. Could you please check the return value of `getaddrinfo` and if res changes after `getaddrinfo` is called? EDIT: I was right: executing your code gives the following error: *ai_family not supported (I used gai_strerror to check). I'm investigating it... – LuxGiammi Dec 31 '20 at 18:42
  • 1
    I assume in case of an error, `getaddrinfo` does not touch the `res` poiner. You need to initialize it to `NULL` on your own prior to the call or you need to take care about return values (which you should always do!). – Gerhardh Dec 31 '20 at 18:53
  • I'd suggest to use `int err = getaddrinfo(NULL, MYPORT, &hints, &res);`, and then `if (err == 0) ... else fprintf(stderr, "%s\n", ai_strerror(err));` – U. Windl Dec 31 '20 at 19:00

1 Answers1

2

I found out the problem...

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>

#define MYPORT "6161"

int main() {
    struct addrinfo hints, *res;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_family = AI_PASSIVE;

    getaddrinfo(NULL, MYPORT, &hints, &res);

    struct addrinfo *addr;
    for (addr = res; addr != NULL; addr = addr->ai_next) {
        printf("Here's one addr!");
    }

    return 0;
}

This is your code.

This is the corrected code:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>

#define MYPORT "6161"

int main() {
    struct addrinfo hints, *res;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    getaddrinfo(NULL, MYPORT, &hints, &res);

    struct addrinfo *addr;
    for (addr = res; addr != NULL; addr = addr->ai_next) {
        printf("Here's one addr!");
    }

    return 0;
}

You just wrote ai_family twice, thus assigning AI_PASSIVE to hints.ai_family instead of hints.ai_flags.

I tried the corrected code and it works fine.

LuxGiammi
  • 631
  • 6
  • 20