2016-09-22 13 views
0

私はCで簡単なサーバ/クライアントプログラムを書いています。どこからでもアクセスできるIP上のポートを開こうとしています。現在、私のサーバは127.0.0.1(ローカルマシン)と0.0.0.0(わかりません)以外は何も動作しません。私はIP_TRANSPARENTオプションを指定しましたが、クライアントを除くすべてのクライアントはまだconnectで失敗します。外部IPへのconnect()が動作しない

サーバー:

// definitions, everything 
struct addrinfo hints, *res; 

hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 

getaddrinfo("192.168.1.1","4001",&hints,&res); 

sockfd = socket(res->ai_family,res->ai_socktype,res->ai_protocol); 

setsockopt(sockfd,IPPROTO_IP,IP_TRANSPARENT,(void*)&sockopt,sizeof(sockopt)); 

bind(sockfd,res->ai_addr,res->ai_addrlen); 
listen(sockfd,0); 

addr_size = sizeof(ext_addr); 
extfd = accept(sockfd,(struct sockaddr *)&ext_addr,&addr_size); 

write(extfd,"Success",7); 
// cleanup 

クライアント:

// definitions, everything 
struct sockaddr_in serv_addr; 

sockfd = socket(AF_INET,SOCK_STREAM,0); 
setsockopt(sockfd,IPPROTO_IP,IP_TRANSPARENT,(void*)&sockopt,sizeof(sockopt)); 

serv_addr.sin_family = AF_INET; 
serv_addr.sin_port = htons(4001); 

inet_pton(AF_INET,"192.168.1.1",&serv_addr.sin_addr); 

connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); // fails here 
read(sockfd,rcvBuf,sizeof(rcvBuf)-1); 

// clean up 

私の問題は何ですか?私は便宜のためにエラーチェックを取り出しました。サーバーは正常に動作しますが、私はそれを確信しています。クライアントは127.0.0.1で正常に動作します。

+0

サーバのIPアドレスは192.168.1.1ですか? – immibis

答えて

3

通常、ローカルマシンに属していないIPにはbind()を割り当てることはできません。しかし、IP_TRANSPARENTドキュメントごと:

IP_TRANSPARENT
する(Linux 2.6.24以降)このブール値のオプションを設定するこのソケットの透過プロキシを有効にします。 このソケットオプションを使用すると、呼び出し側アプリケーションがローカル以外のIPアドレスにバインドし、ローカルアドレスとして外部アドレスを持つクライアントとサーバーの両方として動作することができます。注:これは、外部アドレスに向かうパケットがTProxyボックス(つまり、IP_TRANSPARENTソケットオプションを使用するアプリケーションをホストするシステム)を経由してルーティングされるようにルーティングを設定する必要があります。このソケットオプションを有効にするには、スーパーユーザー権限(CAP_NET_ADMIN機能)が必要です。

iptables TPROXYターゲットを使用したTProxyリダイレクションでも、リダイレクトされたソケットでこのオプションを設定する必要があります。

IP_TRANSPARENTを容易にするためにネットワークに必要なプロキシを設定しましたか?

すぐにIP_TRANSPARENTを無視しましょう。一般的には使われていないので、存在しないふりをしましょう。

127.0.0.1は、IPv4ループバックアドレスです。サーバーをこれにバインドすると、127.0.0.1に接続するローカルIPv4クライアントだけが接続できます。

0.0.0.0はIPv4ワイルドカードアドレスです。サーバーをこれにバインドすると、ソケットはすべてのローカルIPv4アドレスをリッスンします。ローカルマシンまたはネットワーク上の任意のクライアントは、サーバーマシンに属するすべてのIPv4アドレスに接続できます。

192.168.1.1は特定のIPv4アドレスです。サーバーをこれにバインドすると、ソケットはそのIPv4アドレスでのみリッスンします。ローカルマシンまたはネットワーク上のクライアントは、そのIPv4アドレスにのみ接続できます。

クライアントとサーバーが同じマシン上にある場合、クライアントはサーバーがバインドされているすべてのローカルIPに接続できます。

クライアントとサーバーが同じマシン上にない場合、バーは同じネットワーク上にあり、サーバーはそのネットワークにアクセス可能なIPにバインドされているとサーバーに接続できます。つまり、0.0.0.0または192.168.1.1にバインドし、次に192.168.1.1に接続することを意味します。

クライアントとサーバーが同じネットワーク上にない場合、クライアントはパブリックIPを持つルーターの後ろにサーバーがある場合のみ、サーバーに接続できます。サーバは、ルータにアクセス可能なローカルネットワークIPにバインドされていなければなりません。ルータは、パブリックIP上の特定ポートのインバウンド接続をサーバの内部IPに転送するように設定する必要があります。つまり、サーバーを0.0.0.0または192.168.1.1にバインドし、サーバーの内部IPに接続を転送してから、ルーターのパブリックIPに接続します。

+0

'0.0.0.0'にバインドして、同じマシン上で' 192.168.1.1'に接続できますか?それは動作しているように見えないので。 –

+0

@MDXFもし '192.168.1.1'がローカルマシンに属しているならば、ローカルクライアントが' 0.0.0.0'にバインドされているときにローカルクライアントがそれに接続できるはずです。 –

+0

実際に、ホスト '0.0.0.0'のポート' 4001'とホスト '192.168.1.1'とポート' 4001'のクライアントを実行すると、 '接続時にエラーが発生します。 192.168.1.1はネットワークルータに属していませんか? –

関連する問題