📄 sockets.c
字号:
#if APR_TCP_NODELAY_INHERITED
if (apr_is_option_set(sock->netmask, APR_TCP_NODELAY) == 1) {
apr_set_option(&(*new)->netmask, APR_TCP_NODELAY, 1);
}
#endif /* TCP_NODELAY_INHERITED */
#if APR_O_NONBLOCK_INHERITED
if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) == 1) {
apr_set_option(&(*new)->netmask, APR_SO_NONBLOCK, 1);
}
#endif /* APR_O_NONBLOCK_INHERITED */
if (sock->local_interface_unknown ||
!memcmp(sock->local_addr->ipaddr_ptr,
generic_inaddr_any,
sock->local_addr->ipaddr_len)) {
/* If the interface address inside the listening socket's local_addr wasn't
* up-to-date, we don't know local interface of the connected socket either.
*
* If the listening socket was not bound to a specific interface, we
* don't know the local_addr of the connected socket.
*/
(*new)->local_interface_unknown = 1;
}
apr_pool_cleanup_register((*new)->cntxt, (void *)(*new),
socket_cleanup, apr_pool_cleanup_null);
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_socket_connect(apr_socket_t *sock,
apr_sockaddr_t *sa)
{
apr_status_t rv;
if ((sock->socketdes == INVALID_SOCKET) || (!sock->local_addr)) {
return APR_ENOTSOCK;
}
if (connect(sock->socketdes, (const struct sockaddr *)&sa->sa.sin,
sa->salen) == SOCKET_ERROR) {
int rc;
struct timeval tv, *tvptr;
fd_set wfdset, efdset;
rv = apr_get_netos_error();
if (rv != APR_FROM_OS_ERROR(WSAEWOULDBLOCK)) {
return rv;
}
if (sock->timeout == 0) {
/* Tell the app that the connect is in progress...
* Gotta play some games here. connect on Unix will return
* EINPROGRESS under the same circumstances that Windows
* returns WSAEWOULDBLOCK. Do some adhoc canonicalization...
*/
return APR_FROM_OS_ERROR(WSAEINPROGRESS);
}
/* wait for the connect to complete or timeout */
FD_ZERO(&wfdset);
FD_SET(sock->socketdes, &wfdset);
FD_ZERO(&efdset);
FD_SET(sock->socketdes, &efdset);
if (sock->timeout < 0) {
tvptr = NULL;
}
else {
/* casts for winsock/timeval definition */
tv.tv_sec = (long)apr_time_sec(sock->timeout);
tv.tv_usec = (int)apr_time_usec(sock->timeout);
tvptr = &tv;
}
rc = select(FD_SETSIZE+1, NULL, &wfdset, &efdset, tvptr);
if (rc == SOCKET_ERROR) {
return apr_get_netos_error();
}
else if (!rc) {
return APR_FROM_OS_ERROR(WSAETIMEDOUT);
}
/* Evaluate the efdset */
if (FD_ISSET(sock->socketdes, &efdset)) {
/* The connect failed. */
int rclen = sizeof(rc);
if (getsockopt(sock->socketdes, SOL_SOCKET, SO_ERROR, (char*) &rc, &rclen)) {
return apr_get_netos_error();
}
return APR_FROM_OS_ERROR(rc);
}
}
/* connect was OK .. amazing */
sock->remote_addr = sa;
if (sock->local_addr->sa.sin.sin_port == 0) {
sock->local_port_unknown = 1;
}
if (!memcmp(sock->local_addr->ipaddr_ptr,
generic_inaddr_any,
sock->local_addr->ipaddr_len)) {
/* not bound to specific local interface; connect() had to assign
* one for the socket
*/
sock->local_interface_unknown = 1;
}
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_socket_data_get(void **data, const char *key,
apr_socket_t *sock)
{
sock_userdata_t *cur = sock->userdata;
*data = NULL;
while (cur) {
if (!strcmp(cur->key, key)) {
*data = cur->data;
break;
}
cur = cur->next;
}
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_socket_data_set(apr_socket_t *sock, void *data,
const char *key,
apr_status_t (*cleanup)(void *))
{
sock_userdata_t *new = apr_palloc(sock->cntxt, sizeof(sock_userdata_t));
new->key = apr_pstrdup(sock->cntxt, key);
new->data = data;
new->next = sock->userdata;
sock->userdata = new;
if (cleanup) {
apr_pool_cleanup_register(sock->cntxt, data, cleanup, cleanup);
}
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_os_sock_get(apr_os_sock_t *thesock,
apr_socket_t *sock)
{
*thesock = sock->socketdes;
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_os_sock_make(apr_socket_t **apr_sock,
apr_os_sock_info_t *os_sock_info,
apr_pool_t *cont)
{
alloc_socket(apr_sock, cont);
#ifdef APR_ENABLE_FOR_1_0 /* no protocol field yet */
set_socket_vars(*apr_sock, os_sock_info->family, os_sock_info->type, os_sock_info->protocol);
#else
set_socket_vars(*apr_sock, os_sock_info->family, os_sock_info->type, 0);
#endif
(*apr_sock)->timeout = -1;
(*apr_sock)->disconnected = 0;
(*apr_sock)->socketdes = *os_sock_info->os_sock;
if (os_sock_info->local) {
memcpy(&(*apr_sock)->local_addr->sa.sin,
os_sock_info->local,
(*apr_sock)->local_addr->salen);
(*apr_sock)->local_addr->pool = cont;
/* XXX IPv6 - this assumes sin_port and sin6_port at same offset */
(*apr_sock)->local_addr->port = ntohs((*apr_sock)->local_addr->sa.sin.sin_port);
}
else {
(*apr_sock)->local_port_unknown = (*apr_sock)->local_interface_unknown = 1;
}
if (os_sock_info->remote) {
memcpy(&(*apr_sock)->remote_addr->sa.sin,
os_sock_info->remote,
(*apr_sock)->remote_addr->salen);
(*apr_sock)->remote_addr->pool = cont;
/* XXX IPv6 - this assumes sin_port and sin6_port at same offset */
(*apr_sock)->remote_addr->port = ntohs((*apr_sock)->remote_addr->sa.sin.sin_port);
}
else {
(*apr_sock)->remote_addr_unknown = 1;
}
apr_pool_cleanup_register((*apr_sock)->cntxt, (void *)(*apr_sock),
socket_cleanup, apr_pool_cleanup_null);
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock,
apr_os_sock_t *thesock,
apr_pool_t *cont)
{
if ((*sock) == NULL) {
alloc_socket(sock, cont);
/* XXX figure out the actual socket type here */
/* *or* just decide that apr_os_sock_put() has to be told the family and type */
set_socket_vars(*sock, AF_INET, SOCK_STREAM, 0);
(*sock)->timeout = -1;
(*sock)->disconnected = 0;
}
(*sock)->local_port_unknown = (*sock)->local_interface_unknown = 1;
(*sock)->remote_addr_unknown = 1;
(*sock)->socketdes = *thesock;
return APR_SUCCESS;
}
/* Sockets cannot be inherited through the standard sockets
* inheritence. WSADuplicateSocket must be used.
* This is not trivial to implement.
*/
APR_DECLARE(apr_status_t) apr_socket_inherit_set(apr_socket_t *socket)
{
return APR_ENOTIMPL;
}
/* Deprecated */
APR_DECLARE(void) apr_socket_set_inherit(apr_socket_t *socket)
{
apr_socket_inherit_set(socket);
}
APR_DECLARE(apr_status_t) apr_socket_inherit_unset(apr_socket_t *socket)
{
return APR_ENOTIMPL;
}
/* Deprecated */
APR_DECLARE(void) apr_socket_unset_inherit(apr_socket_t *socket)
{
apr_socket_inherit_unset(socket);
}
/* Deprecated */
APR_DECLARE(apr_status_t) apr_shutdown(apr_socket_t *thesocket,
apr_shutdown_how_e how)
{
return apr_socket_shutdown(thesocket, how);
}
/* Deprecated */
APR_DECLARE(apr_status_t) apr_bind(apr_socket_t *sock, apr_sockaddr_t *sa)
{
return apr_socket_bind(sock, sa);
}
/* Deprecated */
APR_DECLARE(apr_status_t) apr_listen(apr_socket_t *sock, apr_int32_t backlog)
{
return apr_socket_listen(sock, backlog);
}
/* Deprecated */
APR_DECLARE(apr_status_t) apr_accept(apr_socket_t **new, apr_socket_t *sock,
apr_pool_t *p)
{
return apr_socket_accept(new, sock, p);
}
/* Deprecated */
APR_DECLARE(apr_status_t) apr_connect(apr_socket_t *sock, apr_sockaddr_t *sa)
{
return apr_socket_connect(sock, sa);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -