我在Windows,Linux,Solaris和HPUX上运行的C应用程序通过套接字调用SSL_read()
和SSL_write()
。在任何版本的OpenSSL中,IPV6是否支持此功能?
从我的搜索来看,这似乎并不明显。我在1.0版本的BIO代码中找到了一些INET6定义。我还在某处读过,为了让IPV6工作,你可以执行指定INET6的普通套接字调用,然后使用BIO_set_fd()
来使IPV6正常工作。这是对的吗?
答案 0 :(得分:1)
我有同样的问题。我必须使用IPV6编写非阻塞TLS服务器。这基本上就是您要使用的:
/* Create a socket BIO attached to an already existing socket
* descriptor. The socket descriptor will be closed when the BIO is
* destroyed. */
bio = BIO_new_socket(sd, BIO_CLOSE);
当然,正如它所说的,您需要首先创建套接字。摘自“带有OpenSSL的网络安全性”,它有点过时了。您需要该书才能正确使用OpenSSL。
尤其令人沮丧的是,没有直接的IPV6支持,因为IPV6 BSD套接字接口(非常糟糕-与IPV4接口一样糟糕)与IPV4 100%兼容。实际上,自从我了解了IPV6 BSD库接口后,我什至不再使用IPV4结构进行编程。
IPV4地址只是:: ffff:xxx.xxx.xxx.xxx-其中xxx.xxx.xxx.xxx是IPV4地址。这是一个将in_addr结构转换为in6_addr结构的函数:
/////////////////////////////////////////////////////////
// NOTE: it's safe for ((void *)pin) == ((void*) pout) //
/////////////////////////////////////////////////////////
struct in6_addr *sockaddr_in_to_6 (struct in_addr *pin, struct in6_addr *pout)
{
// as IPV6 IPV4 address is stored as 0000:0000:0000:0000:0000:FFFF:AABB:CCDD
// where IPV4 address is AA.BB.CC.DD
pout->s6_addr[0x0c] = ( (struct in6_addr *)pin)->s6_addr[0x00];
pout->s6_addr[0x0d] = ( (struct in6_addr *)pin)->s6_addr[0x01];
pout->s6_addr[0x0e] = ( (struct in6_addr *)pin)->s6_addr[0x02];
pout->s6_addr[0x0f] = ( (struct in6_addr *)pin)->s6_addr[0x03];
pout->s6_addr[0x00] = 0x00;
pout->s6_addr[0x01] = 0x00;
pout->s6_addr[0x02] = 0x00;
pout->s6_addr[0x03] = 0x00;
pout->s6_addr[0x04] = 0x00;
pout->s6_addr[0x05] = 0x00;
pout->s6_addr[0x06] = 0x00;
pout->s6_addr[0x06] = 0x00;
pout->s6_addr[0x07] = 0x00;
pout->s6_addr[0x08] = 0x00;
pout->s6_addr[0x09] = 0x00;
pout->s6_addr[0x0a] = 0xFF;
pout->s6_addr[0x0b] = 0xFF;
return pout;
}
您再也不需要使用struct in_addr了,它与IPV4完全兼容。使用IPV6结构中编码的IPV4地址时,实际的网络流量仍为IPV4-至少在Linux下如此。
答案 1 :(得分:0)
我不知道有关OpenSSL和IPv6的详细信息,但从一般角度来看,OpenSSL for TLS连接在TCP层运行,这与IPv4和IPv6相同。没有任何变化会影响您的申请。