Problem with sockets (segfault)

I decided to finally take the time to learn how to use sockets. Anyway, I'm using Beej's guide and I basically copied his server example (to learn how it works).

Anyway, I run the server program:
$ ./socks -p 8080 -q 100 -s
Running with:
	Mode: server (silent mode: off)
	Port: 8080
	Queue length: 100
Starting server mode...
server: bound
server: awaiting client connections


And then I run the UNIX telnet program to try to connect to it:
$ telnet localhost 8080


and... I get a segfault:
Accepting connection... done.
Segmentation fault. Exiting


I've tried other ports such as 3490 (which Beej uses and I in fact used myself at first. 8080 was my second attempt) (if I try reserved ports such as 21 and 80 I get "Permission Denied" and a segfault when trying to bind but that's to be expected -- I don't handle the possibility of a "permission denied"; so obviously I'm gonna get a segfault when I try to connect) but to no avail...

The segfault appears to be occurring near the call to inet_ntop; I've marked the location with /* inet_ntop */ so if you search for that it should take you right to the relevant line...

Here's the whole function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
void server(SERVERCONN* const conn) {
    int res = 0;
    boolean y = True;

    printf("Starting server mode...\n");

    if ((res = getaddrinfo(NULL, conn->port,
                           &conn->hints, &conn->servinfo
                          )) != 0) {

        fprintf(stderr, "server: getaddrinfo error: %s\n", gai_strerror(res));
        die("");
    }

    /* Bind to the first socket connection we can */
    for (conn->p = conn->servinfo; conn->p != NULL; conn->p = conn->p->ai_next) {
        if ((conn->sockfd = socket(conn->p->ai_family, conn->p->ai_socktype,
                                   conn->p->ai_protocol)) == -1) {
            perror("server: socket error");
            continue;
        } 

        if (setsockopt(conn->sockfd, SOL_SOCKET,
                       SO_REUSEADDR, &y, sizeof(int)
                      ) == -1) {
            perror("server: setsockopt error");
            die("");
        }

        if (bind(conn->sockfd, conn->p->ai_addr, conn->p->ai_addrlen) == -1) {
            close(conn->sockfd);
            perror("server: bind error");
            die("");
        }

        break; /* die() or continue should have occurred before here
                * if something went wrong
                */
    }

    if (conn->p == NULL) /* Uh-oh! */
        die("server: failed to bind\n");

    freeaddrinfo(conn->servinfo); /* Free the structure, we don't need it any more */

    printf("server: bound\n");

    if (listen(conn->sockfd, conn->queuelen) == -1) {
        perror("server: listen error");
        die("");
    }

    conn->sa.sa_handler = (void*)handleSignal;
    sigemptyset(&conn->sa.sa_mask);
    conn->sa.sa_flags = SA_RESTART;

    if (sigaction(SIGCHLD, &conn->sa, NULL) == -1) {
        perror("server: sigaction error");
        die("");
    }

    printf("server: awaiting client connections\n");

    for (;;) {
        conn->sin_size   = sizeof(conn->client_addr);
        printf("Accepting connection...");
        conn->new_sockfd = accept(conn->sockfd,
                                  (struct sockaddr*)&(conn->client_addr),
                                  (socklen_t*)&(conn->sin_size)
                                 );
        if (conn->new_sockfd == -1) {
            perror("server: unable to accept client connection");
            continue;
        }

        printf(" done.\n");
        
        /* inet_ntop */

        inet_ntop(conn->client_addr.ss_family,
                  getInAddress((struct sockaddr*)&(conn->client_addr)),
                  conn->addr_str, sizeof(conn->addr_str)
                 );

        printf("server: success; connected to %s\n", conn->addr_str);

        pid_t pid = fork();

        switch (pid) {
            case -1: /* Fuey. */
                perror("server: fork error");
                die("");
            case 0: /* Child process */
                close(conn->sockfd); /* Don't need to listen on the socket */
                if (send(conn->new_sockfd, "HELLO", 13, 0) == -1)
                    perror("server: send error");
                if (send(conn->new_sockfd, "BYE", 13, 0) == -1)
                    perror("server: send error");
                close(conn->new_sockfd); /* Close connection */
                done();
            default:
                close(conn->new_sockfd); /* Don't need to write to the socket */
                break;
        }
    }
}
Last edited on
What does SERVERCONN look like? Specifically, what type is SERVERCONN::addr_str? What does getInAddress() do? Where is it defined?
I thought I posted all that :l
My mistake. I should also have posted that I decided to start again on this, and at any rate I haven't been programming much recently.

Sorry, and thank you for your time :)
Topic archived. No new replies allowed.