3

IPv4 の場合、sendmsg で次の動作が見られます。

10.1.2.3 がクライアント IP であるとします。また、10.1.2.10 は、クライアントのインターフェイスの 1 つで構成されています。

UDP メッセージでは、次の制御情報がパケットに追加されます。

これは、サーバーがクライアントに返信する際に使用する送信元アドレスまたはインターフェイス アドレスです。

cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(sa->sin_addr);
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_SENDSRCADDR_WITH_ERROR;
* (struct in_addr *)CMSG_DATA(cmsg) = sa->sin_addr;
cmsg = (struct cmsghdr *)((caddr_t) cmsg + ALIGN(cmsg->cmsg_len));

メッセージは次のように送信されます。

sendmsg(fd, send_msg, 0);

10.1.2.10 を source-ip として構成し、それを cmsg に追加すると、問題なく動作します。サーバーは 10.1.2.10 に応答します。

しかし、到達不能な IP アドレスまたはクライアントのどのインターフェイスにも構成されていない IP を構成すると、sendmsg は次のエラーで失敗します。

10.1.2.3(10.1.2.3).1813 への sendmsg が失敗しました: 要求されたアドレスを割り当てることができません

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

しかし、IPv6 では同じ動作は見られません。

2001::1 がクライアント IP であるとします。2001::2001 は、クライアントのインターフェイスの 1 つで構成されます。

IPv6 送信元アドレスは、次のように制御メッセージに追加されます。

    cmsg->cmsg_level = IPPROTO_IPV6;
    cmsg->cmsg_type = IPV6_PKTINFO;
    cmsg->cmsg_len =  CMSG_LEN(sizeof(struct in6_pktinfo));
    memcpy((struct in6_addr *)CMSG_DATA(cmsg), &(sa6->sin6_addr),
            sizeof(sa6->sin6_addr));
    cmsg = (struct cmsghdr *)((caddr_t) cmsg + ALIGN(cmsg->cmsg_len));

2001::2001 を source-ip として構成し、サーバーがこのアドレスに返信すると、正常に動作します。

しかし、1001::1001 などの到達不能な IPv6 送信元アドレスを構成すると、IPv4 の場合に見られるような sendmsg からのエラー メッセージは表示されません。メッセージは、2001::1 である元の IPv6 で引き続き送信されます。

誰かが問題の可能性について提案してもらえますか?

ありがとう。

4

2 に答える 2

1

IP_SENDSRCADDR と IPV6_PKTINFO は、2 つの異なる実装である必要があります。おそらく最初のケースでは、エラーを制御するだけです。IPV6_PKTINFO の補助データにインターフェイス インデックスを設定しようとしましたか? IPV6_PKTINFO の場合、補助データのタイプは in6_pktinfo です。

struct in6_pktinfo {
    struct in6_addr ipi6_addr;    /* src/dst IPv6 address */
    unsigned int    ipi6_ifindex; /* send/recv if index */
};

これが何らかの形で役立つことを願っています

于 2013-10-28T22:33:05.330 に答える