2012-03-08 11 views
2

私のプログラムにIPv6サポートを追加したいと思い、奇妙なエラーが発生しました。私は接続を受け入れるソケットを開きたい。 infosocket()コールからのエラー

struct addrinfo hint, *info = NULL; 

memset((void *)&hint, 0, sizeof(hint)); 
hint.ai_family = AF_INET6; 
hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; 
hint.ai_socktype = SOCK_STREAM; 

if ((error = getaddrinfo(NULL, "1234", &hint, &info))) { 
    /* some error handling */ 
} 

I GEN非NULL結果:

まず私はソケットの設定を見つけるにはgetaddrinfo()を使用します。ここに私のシナリオです。それから私は、ソケットを作成したい:

ここ
socket(info->ai_family, info->ai_socktype, info->ai_protocol) 

私はバインドすることができ、私はそれがNULLを返すことを期待するgetaddrinfo()リターンがアドレスのみと考え-1

strerror(errno) 

戻りAddress family not supported by protocol

を取得しますこの場合。私は何が欠けていますか?

私のeth0には現在IPv6アドレスがないことを追加したいと思います。私はuClibcを使用しています。

+0

あなたは何を求めているのですか?そうでなければ 'hint.ai_family = AF_INET6; 'を削除してください – ydroneaud

答えて

1

ai_flagsにAI_ADDRCONFIGを追加して、カーネルがサポートしていないアドレスファミリを返さないようにする必要があります。私は最近、いつもそのフラグを付け加えています。

IPv6を使用しないカーネルをサポートしたい場合は、ai_familyをAF_INET6に設定しないでください。代わりに、返されたすべてのアドレスをリッスンして、AF_INET6のIPV6_V6ONLYを必ず設定してください。残念ながら、AF_INET6アドレスが最初に返されるという保証はありません。

+0

これは私のベーコンを今日保存しました!ありがとうございました! –

+0

@gubblebozer喜んで助けてください。私は今までに、常に最初に 'AF_INET6'をgetaddrinfoに渡してみることに注意したいと思います。もしそれ以降のソケット呼び出しが失敗すると、私は 'AF_INET'にフォールバックします。より多くのコードがありますが、単一のリスニングソケットを使用すると、他の場所での作業が容易になります(これを行う場合は、必ずIPV6_V6ONLYをオフにしてください)。 –

0

getaddrinfostruct addrinfoオブジェクトのリンクリストを返します。これは、ai_nextのメンバーを使ってトラバースできます。接続されるまで(またはNULL /リストの最後に達するまで)返された各オブジェクトを順番に試してください。addrinfo