Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
openssl
提交
5bca70ca
O
openssl
项目概览
btwise
/
openssl
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
openssl
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5bca70ca
编写于
2月 02, 2016
作者:
R
Richard Levitte
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactoring BIO: reimplement old socket handling functions with new ones
Reviewed-by:
N
Kurt Roeckx
<
kurt@openssl.org
>
上级
2fcff74c
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
90 addition
and
435 deletion
+90
-435
crypto/bio/b_sock.c
crypto/bio/b_sock.c
+90
-435
未找到文件。
crypto/bio/b_sock.c
浏览文件 @
5bca70ca
...
...
@@ -88,138 +88,80 @@ static int wsa_init_done = 0;
# define WSAAPI
# endif
/*
* We are currently using deprecated functions here, and GCC warns
* us about them, but since we know, we don't want to hear it.
*/
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
# if OPENSSL_API_COMPAT < 0x10100000L
static
int
get_ip
(
const
char
*
str
,
unsigned
char
*
ip
);
int
BIO_get_host_ip
(
const
char
*
str
,
unsigned
char
*
ip
)
{
int
i
;
int
err
=
1
;
int
locked
=
0
;
struct
hostent
*
he
;
i
=
get_ip
(
str
,
ip
);
if
(
i
<
0
)
{
BIOerr
(
BIO_F_BIO_GET_HOST_IP
,
BIO_R_INVALID_IP_ADDRESS
);
goto
err
;
}
BIO_ADDRINFO
*
res
=
NULL
;
int
ret
=
0
;
/*
* At this point, we have something that is most probably correct in some
* way, so let's init the socket.
*/
if
(
BIO_sock_init
()
!=
1
)
return
0
;
/* don't generate another error code here */
/*
* If the string actually contained an IP address, we need not do
* anything more
*/
if
(
i
>
0
)
return
(
1
);
if
(
BIO_lookup
(
str
,
NULL
,
BIO_LOOKUP_CLIENT
,
AF_INET
,
SOCK_STREAM
,
&
res
))
{
size_t
l
;
/* do a gethostbyname */
CRYPTO_w_lock
(
CRYPTO_LOCK_GETHOSTBYNAME
);
locked
=
1
;
he
=
BIO_gethostbyname
(
str
);
if
(
he
==
NULL
)
{
BIOerr
(
BIO_F_BIO_GET_HOST_IP
,
BIO_R_BAD_HOSTNAME_LOOKUP
);
goto
err
;
}
if
(
BIO_ADDRINFO_family
(
res
)
!=
AF_INET
)
{
BIOerr
(
BIO_F_BIO_GET_HOST_IP
,
BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET
)
;
}
else
{
BIO_ADDR_rawaddress
(
BIO_ADDRINFO_address
(
res
),
NULL
,
&
l
);
/* Because only AF_INET addresses will reach this far,
we can assert that l should be 4 */
OPENSSL_assert
(
l
==
4
);
if
(
he
->
h_addrtype
!=
AF_INET
)
{
BIOerr
(
BIO_F_BIO_GET_HOST_IP
,
BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET
);
goto
err
;
BIO_ADDR_rawaddress
(
BIO_ADDRINFO_address
(
res
),
ip
,
&
l
);
ret
=
1
;
}
BIO_ADDRINFO_free
(
res
);
}
else
{
ERR_add_error_data
(
2
,
"host="
,
str
);
}
for
(
i
=
0
;
i
<
4
;
i
++
)
ip
[
i
]
=
he
->
h_addr_list
[
0
][
i
];
err
=
0
;
err:
if
(
locked
)
CRYPTO_w_unlock
(
CRYPTO_LOCK_GETHOSTBYNAME
);
if
(
err
)
{
ERR_add_error_data
(
2
,
"host="
,
str
);
return
0
;
}
else
return
1
;
return
ret
;
}
int
BIO_get_port
(
const
char
*
str
,
unsigned
short
*
port_ptr
)
{
int
i
;
struct
servent
*
s
;
BIO_ADDRINFO
*
res
=
NULL
;
int
ret
=
0
;
if
(
str
==
NULL
)
{
BIOerr
(
BIO_F_BIO_GET_PORT
,
BIO_R_NO_PORT_DEFINED
);
return
(
0
);
}
i
=
atoi
(
str
);
if
(
i
!=
0
)
*
port_ptr
=
(
unsigned
short
)
i
;
else
{
CRYPTO_w_lock
(
CRYPTO_LOCK_GETSERVBYNAME
);
/*
* Note: under VMS with SOCKETSHR, it seems like the first parameter
* is 'char *', instead of 'const char *'
*/
# ifndef CONST_STRICT
s
=
getservbyname
((
char
*
)
str
,
"tcp"
);
# else
s
=
getservbyname
(
str
,
"tcp"
);
# endif
if
(
s
!=
NULL
)
*
port_ptr
=
ntohs
((
unsigned
short
)
s
->
s_port
);
CRYPTO_w_unlock
(
CRYPTO_LOCK_GETSERVBYNAME
);
if
(
s
==
NULL
)
{
if
(
strcmp
(
str
,
"http"
)
==
0
)
*
port_ptr
=
80
;
else
if
(
strcmp
(
str
,
"telnet"
)
==
0
)
*
port_ptr
=
23
;
else
if
(
strcmp
(
str
,
"socks"
)
==
0
)
*
port_ptr
=
1080
;
else
if
(
strcmp
(
str
,
"https"
)
==
0
)
*
port_ptr
=
443
;
else
if
(
strcmp
(
str
,
"ssl"
)
==
0
)
*
port_ptr
=
443
;
else
if
(
strcmp
(
str
,
"ftp"
)
==
0
)
*
port_ptr
=
21
;
else
if
(
strcmp
(
str
,
"gopher"
)
==
0
)
*
port_ptr
=
70
;
else
{
SYSerr
(
SYS_F_GETSERVBYNAME
,
get_last_socket_error
());
ERR_add_error_data
(
3
,
"service='"
,
str
,
"'"
);
return
(
0
);
}
if
(
BIO_sock_init
()
!=
1
)
return
0
;
/* don't generate another error code here */
if
(
BIO_lookup
(
NULL
,
str
,
BIO_LOOKUP_CLIENT
,
AF_INET
,
SOCK_STREAM
,
&
res
))
{
if
(
BIO_ADDRINFO_family
(
res
)
!=
AF_INET
)
{
BIOerr
(
BIO_F_BIO_GET_PORT
,
BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET
);
}
else
{
*
port_ptr
=
ntohs
(
BIO_ADDR_rawport
(
BIO_ADDRINFO_address
(
res
)));
ret
=
1
;
}
BIO_ADDRINFO_free
(
res
);
}
else
{
ERR_add_error_data
(
2
,
"host="
,
str
);
}
return
(
1
);
return
ret
;
}
# endif
int
BIO_sock_error
(
int
sock
)
{
int
j
,
i
;
union
{
size_t
s
;
int
i
;
}
size
;
/* heuristic way to adapt for platforms that expect 64-bit optlen */
size
.
s
=
0
,
size
.
i
=
sizeof
(
j
);
int
j
=
0
,
i
;
socklen_t
size
=
0
;
/*
* Note: under Windows the third parameter is of type (char *) whereas
* under other systems it is (void *) if you don't have a cast it will
* choke the compiler: if you do have a cast then you can either go for
* (char *) or (void *).
*/
i
=
getsockopt
(
sock
,
SOL_SOCKET
,
SO_ERROR
,
(
void
*
)
&
j
,
(
void
*
)
&
size
);
i
=
getsockopt
(
sock
,
SOL_SOCKET
,
SO_ERROR
,
(
void
*
)
&
j
,
&
size
);
if
(
i
<
0
)
return
(
1
);
else
...
...
@@ -233,11 +175,11 @@ struct hostent *BIO_gethostbyname(const char *name)
* Caching gethostbyname() results forever is wrong, so we have to let
* the true gethostbyname() worry about this
*/
# if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
#
if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
return
gethostbyname
((
char
*
)
name
);
# else
#
else
return
gethostbyname
(
name
);
# endif
#
endif
}
# endif
...
...
@@ -349,364 +291,77 @@ int BIO_socket_ioctl(int fd, long type, void *arg)
# endif
/* __VMS_VER */
# if OPENSSL_API_COMPAT < 0x10100000L
/*
* The reason I have implemented this instead of using sscanf is because
* Visual C 1.52c gives an unresolved external when linking a DLL :-(
*/
static
int
get_ip
(
const
char
*
str
,
unsigned
char
ip
[
4
])
{
unsigned
int
tmp
[
4
];
int
num
=
0
,
c
,
ok
=
0
;
tmp
[
0
]
=
tmp
[
1
]
=
tmp
[
2
]
=
tmp
[
3
]
=
0
;
for
(;;)
{
c
=
*
(
str
++
);
if
((
c
>=
'0'
)
&&
(
c
<=
'9'
))
{
ok
=
1
;
tmp
[
num
]
=
tmp
[
num
]
*
10
+
c
-
'0'
;
if
(
tmp
[
num
]
>
255
)
return
(
0
);
}
else
if
(
c
==
'.'
)
{
if
(
!
ok
)
return
(
-
1
);
if
(
num
==
3
)
return
(
0
);
num
++
;
ok
=
0
;
}
else
if
(
c
==
'\0'
&&
(
num
==
3
)
&&
ok
)
break
;
else
return
(
0
);
}
ip
[
0
]
=
tmp
[
0
];
ip
[
1
]
=
tmp
[
1
];
ip
[
2
]
=
tmp
[
2
];
ip
[
3
]
=
tmp
[
3
];
return
(
1
);
}
int
BIO_get_accept_socket
(
char
*
host
,
int
bind_mode
)
{
int
ret
=
0
;
union
{
struct
sockaddr
sa
;
struct
sockaddr_in
sa_in
;
# if OPENSSL_USE_IPV6
struct
sockaddr_in6
sa_in6
;
# endif
}
server
,
client
;
int
s
=
(
int
)
INVALID_SOCKET
,
cs
,
addrlen
;
unsigned
char
ip
[
4
];
unsigned
short
port
;
char
*
str
=
NULL
,
*
e
;
char
*
h
,
*
p
;
unsigned
long
l
;
int
err_num
;
int
s
=
INVALID_SOCKET
;
char
*
h
=
NULL
,
*
p
=
NULL
;
BIO_ADDRINFO
*
res
=
NULL
;
if
(
BIO_sock_init
()
!=
1
)
return
((
int
)
INVALID_SOCKET
);
if
((
str
=
OPENSSL_strdup
(
host
))
==
NULL
)
return
((
int
)
INVALID_SOCKET
);
h
=
p
=
NULL
;
h
=
str
;
for
(
e
=
str
;
*
e
;
e
++
)
{
if
(
*
e
==
':'
)
{
p
=
e
;
}
else
if
(
*
e
==
'/'
)
{
*
e
=
'\0'
;
break
;
}
}
if
(
p
)
*
p
++
=
'\0'
;
/* points at last ':', '::port' is special
* [see below] */
else
p
=
h
,
h
=
NULL
;
# ifdef EAI_FAMILY
do
{
static
union
{
void
*
p
;
int
(
WSAAPI
*
f
)
(
const
char
*
,
const
char
*
,
const
struct
addrinfo
*
,
struct
addrinfo
**
);
}
p_getaddrinfo
=
{
NULL
};
static
union
{
void
*
p
;
void
(
WSAAPI
*
f
)
(
struct
addrinfo
*
);
}
p_freeaddrinfo
=
{
NULL
};
struct
addrinfo
*
res
,
hint
;
if
(
p_getaddrinfo
.
p
==
NULL
)
{
if
((
p_getaddrinfo
.
p
=
DSO_global_lookup
(
"getaddrinfo"
))
==
NULL
||
(
p_freeaddrinfo
.
p
=
DSO_global_lookup
(
"freeaddrinfo"
))
==
NULL
)
p_getaddrinfo
.
p
=
(
void
*
)
-
1
;
}
if
(
p_getaddrinfo
.
p
==
(
void
*
)
-
1
)
break
;
if
(
!
BIO_parse_hostserv
(
host
,
&
h
,
&
p
,
BIO_PARSE_PRIO_SERV
))
return
INVALID_SOCKET
;
/*
* '::port' enforces IPv6 wildcard listener. Some OSes, e.g. Solaris,
* default to IPv6 without any hint. Also note that commonly IPv6
* wildchard socket can service IPv4 connections just as well...
*/
memset
(
&
hint
,
0
,
sizeof
(
hint
));
hint
.
ai_flags
=
AI_PASSIVE
;
if
(
h
)
{
if
(
strchr
(
h
,
':'
))
{
if
(
h
[
1
]
==
'\0'
)
h
=
NULL
;
# if OPENSSL_USE_IPV6
hint
.
ai_family
=
AF_INET6
;
# else
h
=
NULL
;
# endif
}
else
if
(
h
[
0
]
==
'*'
&&
h
[
1
]
==
'\0'
)
{
hint
.
ai_family
=
AF_INET
;
h
=
NULL
;
}
}
if
((
*
p_getaddrinfo
.
f
)
(
h
,
p
,
&
hint
,
&
res
))
break
;
addrlen
=
res
->
ai_addrlen
<=
sizeof
(
server
)
?
res
->
ai_addrlen
:
sizeof
(
server
);
memcpy
(
&
server
,
res
->
ai_addr
,
addrlen
);
(
*
p_freeaddrinfo
.
f
)
(
res
);
goto
again
;
}
while
(
0
);
# endif
if
(
BIO_sock_init
()
!=
1
)
return
INVALID_SOCKET
;
if
(
!
BIO_get_port
(
p
,
&
port
)
)
if
(
BIO_lookup
(
h
,
p
,
BIO_LOOKUP_SERVER
,
AF_UNSPEC
,
SOCK_STREAM
,
&
res
)
!=
0
)
goto
err
;
memset
(
&
server
,
0
,
sizeof
(
server
));
server
.
sa_in
.
sin_family
=
AF_INET
;
server
.
sa_in
.
sin_port
=
htons
(
port
);
addrlen
=
sizeof
(
server
.
sa_in
);
if
(
h
==
NULL
||
strcmp
(
h
,
"*"
)
==
0
)
server
.
sa_in
.
sin_addr
.
s_addr
=
INADDR_ANY
;
else
{
if
(
!
BIO_get_host_ip
(
h
,
&
(
ip
[
0
])))
goto
err
;
l
=
(
unsigned
long
)
((
unsigned
long
)
ip
[
0
]
<<
24L
)
|
((
unsigned
long
)
ip
[
1
]
<<
16L
)
|
((
unsigned
long
)
ip
[
2
]
<<
8L
)
|
((
unsigned
long
)
ip
[
3
]);
server
.
sa_in
.
sin_addr
.
s_addr
=
htonl
(
l
);
}
again:
s
=
socket
(
server
.
sa
.
sa_family
,
SOCK_STREAM
,
SOCKET_PROTOCOL
);
if
(
s
==
(
int
)
INVALID_SOCKET
)
{
SYSerr
(
SYS_F_SOCKET
,
get_last_socket_error
());
ERR_add_error_data
(
3
,
"port='"
,
host
,
"'"
);
BIOerr
(
BIO_F_BIO_GET_ACCEPT_SOCKET
,
BIO_R_UNABLE_TO_CREATE_SOCKET
);
if
((
s
=
BIO_socket
(
BIO_ADDRINFO_family
(
res
),
BIO_ADDRINFO_socktype
(
res
),
BIO_ADDRINFO_protocol
(
res
),
0
))
==
INVALID_SOCKET
)
{
s
=
INVALID_SOCKET
;
goto
err
;
}
# ifdef SO_REUSEADDR
if
(
bind_mode
==
BIO_BIND_REUSEADDR
)
{
int
i
=
1
;
ret
=
setsockopt
(
s
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
char
*
)
&
i
,
sizeof
(
i
));
bind_mode
=
BIO_BIND_NORMAL
;
}
# endif
if
(
bind
(
s
,
&
server
.
sa
,
addrlen
)
==
-
1
)
{
# ifdef SO_REUSEADDR
err_num
=
get_last_socket_error
();
if
((
bind_mode
==
BIO_BIND_REUSEADDR_IF_UNUSED
)
&&
# ifdef OPENSSL_SYS_WINDOWS
/*
* Some versions of Windows define EADDRINUSE to a dummy value.
*/
(
err_num
==
WSAEADDRINUSE
))
# else
(
err_num
==
EADDRINUSE
))
# endif
{
client
=
server
;
if
(
h
==
NULL
||
strcmp
(
h
,
"*"
)
==
0
)
{
# if OPENSSL_USE_IPV6
if
(
client
.
sa
.
sa_family
==
AF_INET6
)
{
memset
(
&
client
.
sa_in6
.
sin6_addr
,
0
,
sizeof
(
client
.
sa_in6
.
sin6_addr
));
client
.
sa_in6
.
sin6_addr
.
s6_addr
[
15
]
=
1
;
}
else
# endif
if
(
client
.
sa
.
sa_family
==
AF_INET
)
{
client
.
sa_in
.
sin_addr
.
s_addr
=
htonl
(
0x7F000001
);
}
else
goto
err
;
}
cs
=
socket
(
client
.
sa
.
sa_family
,
SOCK_STREAM
,
SOCKET_PROTOCOL
);
if
(
cs
!=
(
int
)
INVALID_SOCKET
)
{
int
ii
;
ii
=
connect
(
cs
,
&
client
.
sa
,
addrlen
);
closesocket
(
cs
);
if
(
ii
==
(
int
)
INVALID_SOCKET
)
{
bind_mode
=
BIO_BIND_REUSEADDR
;
closesocket
(
s
);
goto
again
;
}
/* else error */
}
/* else error */
}
# endif
SYSerr
(
SYS_F_BIND
,
err_num
);
ERR_add_error_data
(
3
,
"port='"
,
host
,
"'"
);
BIOerr
(
BIO_F_BIO_GET_ACCEPT_SOCKET
,
BIO_R_UNABLE_TO_BIND_SOCKET
);
goto
err
;
}
if
(
listen
(
s
,
MAX_LISTEN
)
==
-
1
)
{
SYSerr
(
SYS_F_BIND
,
get_last_socket_error
());
ERR_add_error_data
(
3
,
"port='"
,
host
,
"'"
);
BIOerr
(
BIO_F_BIO_GET_ACCEPT_SOCKET
,
BIO_R_UNABLE_TO_LISTEN_SOCKET
);
goto
err
;
if
(
!
BIO_listen
(
s
,
BIO_ADDRINFO_address
(
res
),
bind_mode
?
BIO_SOCK_REUSEADDR
:
0
))
{
BIO_closesocket
(
s
);
s
=
INVALID_SOCKET
;
}
ret
=
1
;
err:
OPENSSL_free
(
str
);
if
((
ret
==
0
)
&&
(
s
!=
(
int
)
INVALID_SOCKET
))
{
closesocket
(
s
);
s
=
(
int
)
INVALID_SOCKET
;
}
return
(
s
);
BIO_ADDRINFO_free
(
res
);
OPENSSL_free
(
h
);
OPENSSL_free
(
p
);
return
s
;
}
int
BIO_accept
(
int
sock
,
char
**
addr
)
int
BIO_accept
(
int
sock
,
char
**
ip_port
)
{
int
ret
=
(
int
)
INVALID_SOCKET
;
unsigned
long
l
;
unsigned
short
port
;
char
*
p
;
BIO_ADDR
*
res
=
BIO_ADDR_new
();
int
ret
=
-
1
;
struct
{
/*
* As for following union. Trouble is that there are platforms
* that have socklen_t and there are platforms that don't, on
* some platforms socklen_t is int and on some size_t. So what
* one can do? One can cook #ifdef spaghetti, which is nothing
* but masochistic. Or one can do union between int and size_t.
* One naturally does it primarily for 64-bit platforms where
* sizeof(int) != sizeof(size_t). But would it work? Note that
* if size_t member is initialized to 0, then later int member
* assignment naturally does the job on little-endian platforms
* regardless accept's expectations! What about big-endians?
* If accept expects int*, then it works, and if size_t*, then
* length value would appear as unreasonably large. But this
* won't prevent it from filling in the address structure. The
* trouble of course would be if accept returns more data than
* actual buffer can accomodate and overwrite stack... That's
* where early OPENSSL_assert comes into picture. Besides, the
* only 64-bit big-endian platform found so far that expects
* size_t* is HP-UX, where stack grows towards higher address.
* <appro>
*/
union
{
size_t
s
;
int
i
;
}
len
;
union
{
struct
sockaddr
sa
;
struct
sockaddr_in
sa_in
;
# if OPENSSL_USE_IPV6
struct
sockaddr_in6
sa_in6
;
# endif
}
from
;
}
sa
;
sa
.
len
.
s
=
0
;
sa
.
len
.
i
=
sizeof
(
sa
.
from
);
memset
(
&
sa
.
from
,
0
,
sizeof
(
sa
.
from
));
ret
=
accept
(
sock
,
&
sa
.
from
.
sa
,
(
void
*
)
&
sa
.
len
);
if
(
sizeof
(
sa
.
len
.
i
)
!=
sizeof
(
sa
.
len
.
s
)
&&
sa
.
len
.
i
==
0
)
{
OPENSSL_assert
(
sa
.
len
.
s
<=
sizeof
(
sa
.
from
));
sa
.
len
.
i
=
(
int
)
sa
.
len
.
s
;
/* use sa.len.i from this point */
if
(
res
==
NULL
)
{
BIOerr
(
BIO_F_BIO_ACCEPT
,
ERR_R_MALLOC_FAILURE
);
return
ret
;
}
ret
=
BIO_accept_ex
(
sock
,
res
,
0
);
if
(
ret
==
(
int
)
INVALID_SOCKET
)
{
if
(
BIO_sock_should_retry
(
ret
))
return
-
2
;
if
(
BIO_sock_should_retry
(
ret
))
{
ret
=
-
2
;
goto
end
;
}
SYSerr
(
SYS_F_ACCEPT
,
get_last_socket_error
());
BIOerr
(
BIO_F_BIO_ACCEPT
,
BIO_R_ACCEPT_ERROR
);
goto
end
;
}
if
(
addr
==
NULL
)
goto
end
;
# ifdef EAI_FAMILY
do
{
char
h
[
NI_MAXHOST
],
s
[
NI_MAXSERV
];
size_t
nl
;
static
union
{
void
*
p
;
int
(
WSAAPI
*
f
)
(
const
struct
sockaddr
*
,
size_t
/* socklen_t */
,
char
*
,
size_t
,
char
*
,
size_t
,
int
);
}
p_getnameinfo
=
{
NULL
};
/*
* 2nd argument to getnameinfo is specified to be socklen_t.
* Unfortunately there is a number of environments where socklen_t is
* not defined. As it's passed by value, it's safe to pass it as
* size_t... <appro>
*/
if
(
p_getnameinfo
.
p
==
NULL
)
{
if
((
p_getnameinfo
.
p
=
DSO_global_lookup
(
"getnameinfo"
))
==
NULL
)
p_getnameinfo
.
p
=
(
void
*
)
-
1
;
}
if
(
p_getnameinfo
.
p
==
(
void
*
)
-
1
)
break
;
if
((
*
p_getnameinfo
.
f
)
(
&
sa
.
from
.
sa
,
sa
.
len
.
i
,
h
,
sizeof
(
h
),
s
,
sizeof
(
s
),
NI_NUMERICHOST
|
NI_NUMERICSERV
))
break
;
nl
=
strlen
(
h
)
+
strlen
(
s
)
+
2
;
p
=
*
addr
;
if
(
p
)
*
p
=
'\0'
;
p
=
OPENSSL_realloc
(
p
,
nl
);
if
(
p
==
NULL
)
{
BIOerr
(
BIO_F_BIO_ACCEPT
,
ERR_R_MALLOC_FAILURE
);
goto
end
;
}
*
addr
=
p
;
BIO_snprintf
(
*
addr
,
nl
,
"%s:%s"
,
h
,
s
);
goto
end
;
}
while
(
0
);
# endif
if
(
sa
.
from
.
sa
.
sa_family
!=
AF_INET
)
goto
end
;
l
=
ntohl
(
sa
.
from
.
sa_in
.
sin_addr
.
s_addr
);
port
=
ntohs
(
sa
.
from
.
sa_in
.
sin_port
);
if
(
*
addr
==
NULL
)
{
if
((
p
=
OPENSSL_malloc
(
24
))
==
NULL
)
{
BIOerr
(
BIO_F_BIO_ACCEPT
,
ERR_R_MALLOC_FAILURE
);
goto
end
;
}
*
addr
=
p
;
if
(
ip_port
!=
NULL
)
{
char
*
host
=
BIO_ADDR_hostname_string
(
res
,
1
);
char
*
port
=
BIO_ADDR_service_string
(
res
,
1
);
*
ip_port
=
OPENSSL_zalloc
(
strlen
(
host
)
+
strlen
(
port
)
+
2
);
strcpy
(
*
ip_port
,
host
);
strcat
(
*
ip_port
,
":"
);
strcat
(
*
ip_port
,
port
);
OPENSSL_free
(
host
);
OPENSSL_free
(
port
);
}
BIO_snprintf
(
*
addr
,
24
,
"%d.%d.%d.%d:%d"
,
(
unsigned
char
)(
l
>>
24L
)
&
0xff
,
(
unsigned
char
)(
l
>>
16L
)
&
0xff
,
(
unsigned
char
)(
l
>>
8L
)
&
0xff
,
(
unsigned
char
)(
l
)
&
0xff
,
port
);
end:
return
(
ret
);
BIO_ADDR_free
(
res
);
return
ret
;
}
# endif
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录