mdietz
mdietz

Reputation: 53

Basic C Server: Connection Refused Error

I have a program that should accept a connection at port 62085 and sends back a test message. The code hangs at accept() and never returns even if the client tries to connect. Why does the server refuse the connections? Could it be a firewall problem?

This code works for me when compiled under OS X 10.8.3, but refuses connections when running on Oracle Enterprise Linux. accept() will never accept a connection, and telnet to the port from another device gives a Connection Refused error. The below is output from netstat that proves the program is in fact listening on the port I want. I have tried other ports, 62084, 666 and 8080 to see if there was something blocking that particular port. (The netstat outputs were from two different commands).

   tcp        0      0 0.0.0.0:62085               0.0.0.0:*                   LISTEN      11815/del-chef  

   tcp        0      0 129.133.124.83:62085        0.0.0.0:*                   LISTEN      15101/del-chef  

iptables shows that it is allowing connections on all ports as well.

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:yo-main 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:terabase 
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination`

And the output of sudo iptables -t mangle -L is

the output of that command is

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

Both the OS X device and Enterprise Linux Server are running on the same network, so I am befuddled as to why when I execute telnet XXX.XXX.XXX.XXX 62085 I receive a Connection Refused error.

The relevant code is below:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netdb.h>
#include <fcntl.h>
#include <syslog.h>
#include <signal.h>

#define BACKLOG 10
#define PORT "62085"

void main() {
    struct sockaddr_in cli_addr;
    socklen_t addr_size;
    struct addrinfo hints, *res, *p;
    int sockfd, new_fd;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;  // use IPv4
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;     // fill in my IP for me

    if (getaddrinfo(NULL, PORT, &hints, &res) != 0){
        syslog(LOG_ERR, "getaddrinfo() error");
        exit(1);
    }
    for (p = res; p != NULL; p = p->ai_next){
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
            syslog(LOG_ERR, "Error creating socket");
            continue;
        }
        int yes = 1;
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
            syslog(LOG_ERR, "Error settings socket options");
            exit(1);
        }
        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
            close(sockfd);
            syslog(LOG_ERR, "Error binding socket");
            continue;
        }

        break;    
    }
    if (p == NULL){
        close(sockfd);
        syslog(LOG_ERR, "Error binding socket");
        exit(1);
    }
    freeaddrinfo(res); // free memory now that it is no longer in use

    if (listen(sockfd, BACKLOG) == -1){
        close(sockfd);
        syslog(LOG_ERR, "Error listening");
        exit(1);
    }
    syslog(LOG_INFO, "Waiting for connections");
    addr_size = sizeof(cli_addr);
    if (new_fd = accept(sockfd, (struct sockaddr *)&cli_addr, &addr_size) == -1){
        syslog(LOG_ERR, "Error accepting connection");
    }
}

Upvotes: 3

Views: 2379

Answers (2)

mdietz
mdietz

Reputation: 53

Turns out it was iptables, issuing service stop iptables allowed the code to work. I ended up adding the following rule to iptables:

sudo iptables -I INPUT 5 -m state --state NEW -m tcp -p tcp --dport 62085 -j ACCEPT

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 597961

There is nothing wrong with the code you have shown, so the problem is external to your app. Since your socket is clearly listening and bas not exhausted its backlog yet, then the connection refused error has to mean that the OS itself, or possibly/likely a firewall/router, is refusing the connection before it reaches your app.

Upvotes: 2

Related Questions