Reputation: 53
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
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
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