3

ポート 62085 で接続を受け入れ、テスト メッセージを送り返すプログラムがあります。コードは accept() でハングし、クライアントが接続を試みても戻りません。サーバーが接続を拒否するのはなぜですか? ファイアウォールの問題でしょうか?

このコードは、OS X 10.8.3 でコンパイルすると機能しますが、Oracle Enterprise Linux で実行すると接続を拒否します。 accept()接続を受け入れず、別のデバイスからポートへの telnet でConnection Refusedエラーが発生します。以下は、プログラムが実際に必要なポートでリッスンしていることを証明する netstat からの出力です。他のポート 62084、666、および 8080 を試して、その特定のポートをブロックしているものがあるかどうかを確認しました。(netstat の出力は、2 つの異なるコマンドからのものです)。

   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 は、すべてのポートでも接続を許可していることを示しています。

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`

そして、の出力sudo iptables -t mangle -L

そのコマンドの出力は

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         

OS X デバイスと Enterprise Linux Server の両方が同じネットワーク上で実行されているため、実行時にエラーが発生する理由について困惑してtelnet XXX.XXX.XXX.XXX 62085Connection Refusedます。

関連するコードは次のとおりです。

#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");
    }
}
4

2 に答える 2

0

それは iptables であることが判明し、発行service stop iptablesするとコードが機能するようになりました。最終的に、次のルールを iptables に追加しました。

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

于 2013-05-02T18:18:42.153 に答える