rbb 99/06/14 12:11:18
Added: apr/network_io/win32 network_io.def network_io.dsp
networkio.h poll.c sendrecv.c sockets.c sockopt.c
Log:
First pass at Windows Network I/O. Couldn't get WSARecv to work, but I am
still working
on it. This mostly works, and it provides a select implementation that
mimics poll. Not
sure the select works yet, but it's close. I'll update it as soon as I fix
the rest of the
bugs.
Revision Changes Path
1.1 apache-apr/apr/network_io/win32/network_io.def
Index: network_io.def
===================================================================
; network_io.def :
LIBRARY network_io
DESCRIPTION ''
EXPORTS
; Add new API calls to the end of this list.
ap_create_tcp_socket @1
ap_shutdown @2
ap_close_socket @3
ap_bind @4
ap_listen @5
ap_accept @6
ap_connect @7
ap_get_remote_hostname @8
ap_gethostname @9
ap_send @10
ap_recv @11
ap_setsocketopt @12
ap_setport @13
ap_setup_poll @14
ap_poll @15
ap_add_poll_socket @16
ap_get_revents @17
1.1 apache-apr/apr/network_io/win32/network_io.dsp
Index: network_io.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="network_io" - Package
Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=network_io - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "network_io.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "network_io.mak" CFG="network_io - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "network_io - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "network_io - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "network_io - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"
/YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX
/FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib
odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib
odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "network_io - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D
"_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /I
"..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib
odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib
odbccp32.lib ws2_32.lib ..\..\lib\Debug\lib.lib
..\..\misc\win32\Debug\misc.lib /nologo /subsystem:windows /dll /debug
/machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "network_io - Win32 Release"
# Name "network_io - Win32 Debug"
# Begin Source File
SOURCE=.\network_io.def
# End Source File
# Begin Source File
SOURCE=.\networkio.h
# End Source File
# Begin Source File
SOURCE=.\poll.c
# End Source File
# Begin Source File
SOURCE=.\sendrecv.c
# End Source File
# Begin Source File
SOURCE=.\sockets.c
# End Source File
# Begin Source File
SOURCE=.\sockopt.c
# End Source File
# End Target
# End Project
1.1 apache-apr/apr/network_io/win32/networkio.h
Index: networkio.h
===================================================================
/* ====================================================================
* Copyright (c) 1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#ifndef NETWORK_IO_H
#define NETWORK_IO_H
#include "apr_network_io.h"
#include "apr_general.h"
struct socket_t {
ap_context_t *cntxt;
SOCKET sock;
char *remote_hostname;
struct sockaddr_in *addr;
size_t addr_len;
};
struct pollfd_t {
ap_context_t *cntxt;
fd_set read;
fd_set write;
fd_set except;
};
#endif /* ! NETWORK_IO_H */
1.1 apache-apr/apr/network_io/win32/poll.c
Index: poll.c
===================================================================
/* ====================================================================
* Copyright (c) 1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#include "networkio.h"
#include "apr_network_io.h"
#include "apr_general.h"
#include "apr_lib.h"
#include <errno.h>
#include <windows.h>
#include <time.h>
ap_status_t ap_setup_poll(ap_context_t *cont, ap_int32_t num, struct pollfd_t
**new)
{
(*new) = (struct pollfd_t *)ap_palloc(cont, sizeof(struct pollfd_t) *
num);
if ((*new) == NULL) {
return APR_ENOMEM;
}
(*new)->cntxt = cont;
FD_ZERO(&(*new)->read);
FD_ZERO(&(*new)->write);
FD_ZERO(&(*new)->except);
return APR_SUCCESS;
}
ap_status_t ap_add_poll_socket(struct pollfd_t *aprset,
struct socket_t *sock, ap_int16_t event)
{
if (event & APR_POLLIN) {
FD_SET(sock->sock, &aprset->read);
}
if (event & APR_POLLPRI) {
FD_SET(sock->sock, &aprset->read);
}
if (event & APR_POLLOUT) {
FD_SET(sock->sock, &aprset->write);
}
if (event & APR_POLLERR) {
FD_SET(sock->sock, &aprset->except);
}
if (event & APR_POLLHUP) {
FD_SET(sock->sock, &aprset->except);
}
if (event & APR_POLLNVAL) {
FD_SET(sock->sock, &aprset->except);
}
return APR_SUCCESS;
}
ap_status_t ap_poll(struct pollfd_t *aprset, ap_int32_t *nsds, ap_int32_t
timeout)
{
int rv;
struct timeval *thetime;
if (timeout == -1) {
thetime = NULL;
}
else {
/* Convert milli-seconds into seconds and micro-seconds. */
thetime = (struct timeval *)ap_palloc(aprset->cntxt, sizeof(struct
timeval));
thetime->tv_sec = timeout / (1000);
timeout = timeout % 1000;
thetime->tv_usec = timeout * 1000;
}
rv = select(500, &aprset->read, &aprset->read, &aprset->read,
thetime);
(*nsds) = rv;
if ((*nsds) < 0) {
return APR_EEXIST;
}
return APR_SUCCESS;
}
ap_status_t ap_get_revents(struct pollfd_t *aprset, struct socket_t *sock,
ap_int16_t *event)
{
ap_int16_t revents = 0;
WSABUF data;
int dummy;
int flags = MSG_PEEK;
/* We just want to PEEK at the data, so I am setting up a dummy WSABUF
* variable here.
*/
data.len = 256;
data.buf = (char *)ap_palloc(aprset->cntxt, 256);
if (FD_ISSET(sock->sock, &aprset->read)) {
revents |= APR_POLLIN;
if (WSARecv(sock->sock, &data, 1, &dummy, &flags, NULL,
NULL) == SOCKET_ERROR) {
dummy = WSAGetLastError();
switch (dummy) {
case WSAECONNRESET:
case WSAECONNABORTED:
case WSAESHUTDOWN:
case WSAENETRESET: {
revents ^= APR_POLLIN;
revents |= APR_POLLHUP;
break;
}
case WSAENOTSOCK: {
revents ^= APR_POLLIN;
revents |= APR_POLLNVAL;
}
default: {
revents ^= APR_POLLIN;
revents |= APR_POLLERR;
}
}
}
}
if (FD_ISSET(sock->sock, &aprset->write)) {
revents |= APR_POLLOUT;
}
/* I am assuming that the except is for out of band data, not a failed
* connection on a non-blocking socket. Might be a bad assumption, but
* it works for now. rbb.
*/
if (FD_ISSET(sock->sock, &aprset->except)) {
revents |= APR_POLLPRI;
}
(*event) = revents;
return APR_SUCCESS;
}
1.1 apache-apr/apr/network_io/win32/sendrecv.c
Index: sendrecv.c
===================================================================
/* ====================================================================
* Copyright (c) 1996-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#include "networkio.h"
#include "apr_errno.h"
#include "apr_general.h"
#include "apr_network_io.h"
#include "apr_lib.h"
#include <time.h>
ap_status_t ap_send(struct socket_t *sock, const char *buf, ap_ssize_t *len,
time_t sec)
{
ap_ssize_t rv;
WSABUF data;
int lasterror;
data.len = *len;
data.buf = ap_pstrdup(sock->cntxt, buf);
do {
rv = WSASend(sock->sock, &data, 1, len, 0, NULL, NULL);
if (rv == SOCKET_ERROR) {
lasterror = WSAGetLastError();
}
} while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
if (rv == SOCKET_ERROR && lasterror == WSAEWOULDBLOCK && sec > 0) {
struct timeval tv;
fd_set fdset;
int srv;
do {
FD_ZERO(&fdset);
FD_SET(sock->sock, &fdset);
tv.tv_sec = sec;
tv.tv_usec = 0;
srv = select(FD_SETSIZE, NULL, &fdset, NULL, &tv);
if (srv == SOCKET_ERROR) {
lasterror = WSAGetLastError();
}
} while (srv == SOCKET_ERROR && errno == WSAEINTR);
if (srv == 0) {
(*len) = -1;
return APR_TIMEUP;
}
if (srv < 0) {
(*len) = -1;
return APR_EEXIST;
}
else {
do {
rv = WSASend(sock->sock, &data, 1, len, 0, NULL, NULL);
if (rv == SOCKET_ERROR) {
lasterror = WSAGetLastError();
}
} while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
}
}
return APR_SUCCESS;
}
ap_status_t ap_recv(struct socket_t *sock, char *buf, ap_ssize_t *len, time_t
sec)
{
ap_ssize_t rv;
int lasterror;
do {
rv = recv(sock->sock, buf, *len, 0);
if (rv == SOCKET_ERROR) {
lasterror = WSAGetLastError();
}
} while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
if (rv == SOCKET_ERROR && lasterror == WSAEWOULDBLOCK && sec > 0) {
struct timeval tv;
fd_set fdset;
int srv;
do {
FD_ZERO(&fdset);
FD_SET(sock->sock, &fdset);
tv.tv_sec = sec;
tv.tv_usec = 0;
srv = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
if (srv == SOCKET_ERROR) {
lasterror = WSAGetLastError();
}
} while (srv == SOCKET_ERROR && errno == WSAEINTR);
if (srv == 0) {
(*len) = -1;
return APR_TIMEUP;
}
else if (srv < 0) {
(*len) = -1;
return errno;
}
else {
do {
rv = recv(sock->sock, buf, *len, 0);
if (rv == SOCKET_ERROR) {
lasterror = WSAGetLastError();
}
} while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
}
}
(*len) = rv;
return APR_SUCCESS;
}
1.1 apache-apr/apr/network_io/win32/sockets.c
Index: sockets.c
===================================================================
/* ====================================================================
* Copyright (c) 1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#include "networkio.h"
#include "apr_network_io.h"
#include "apr_general.h"
#include "apr_lib.h"
#include <string.h>
#include <winsock2.h>
#include <windows.h>
ap_status_t socket_cleanup(void *sock)
{
struct socket_t *thesocket = sock;
if (closesocket(thesocket->sock) != SOCKET_ERROR) {
thesocket->sock = INVALID_SOCKET;
return APR_SUCCESS;
}
else {
return APR_EEXIST;
}
}
ap_status_t ap_create_tcp_socket(ap_context_t *cont, struct socket_t **new)
{
(*new) = (struct socket_t *)ap_palloc(cont, sizeof(struct socket_t));
if ((*new) == NULL) {
return APR_ENOMEM;
}
(*new)->cntxt = cont;
(*new)->addr = (struct sockaddr_in *)ap_pcalloc((*new)->cntxt,
sizeof(struct sockaddr_in));
if ((*new)->addr == NULL) {
return APR_ENOMEM;
}
/* For right now, we are not using socket groups. We may later.
* No flags to use when creating a socket, so use 0 for that parameter as
well.
*/
(*new)->sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
(*new)->remote_hostname = NULL;
(*new)->addr->sin_family = AF_INET;
(*new)->addr_len = sizeof(*(*new)->addr);
(*new)->addr->sin_port = 0;
if ((*new)->sock == INVALID_SOCKET) {
return APR_EEXIST;
}
ap_register_cleanup((*new)->cntxt, (void *)(*new),
socket_cleanup, NULL);
return APR_SUCCESS;
}
ap_status_t ap_shutdown(struct socket_t *thesocket, ap_shutdown_how_e how)
{
int winhow;
switch (how) {
case APR_SHUTDOWN_READ: {
winhow = SD_RECEIVE;
break;
}
case APR_SHUTDOWN_WRITE: {
winhow = SD_SEND;
break;
}
case APR_SHUTDOWN_READWRITE: {
winhow = SD_BOTH;
break;
}
}
if (shutdown(thesocket->sock, winhow) == 0) {
return APR_SUCCESS;
}
else {
return APR_EEXIST;
}
}
ap_status_t ap_close_socket(struct socket_t *thesocket)
{
ap_kill_cleanup(thesocket->cntxt, thesocket, socket_cleanup);
return socket_cleanup(thesocket);
}
ap_status_t ap_setport(struct socket_t *sock, ap_uint32_t port)
{
if (WSAHtons(sock->sock, (short)port, &sock->addr->sin_port) != 0) {
return APR_EEXIST;
}
return APR_SUCCESS;
}
ap_status_t ap_bind(struct socket_t *sock)
{
sock->addr->sin_addr.s_addr = INADDR_ANY;
if (bind(sock->sock, (struct sockaddr *)sock->addr, sock->addr_len) ==
-1) {
return errno;
}
else
return APR_SUCCESS;
}
ap_status_t ap_listen(struct socket_t *sock, ap_int32_t backlog)
{
if (listen(sock->sock, backlog) == SOCKET_ERROR)
return APR_EEXIST;
else
return APR_SUCCESS;
}
ap_status_t ap_accept(const struct socket_t *sock, struct socket_t **new)
{
struct hostent *hptr;
(*new) = (struct socket_t *)ap_palloc(sock->cntxt,
sizeof(struct socket_t));
(*new)->cntxt = sock->cntxt;
(*new)->addr = (struct sockaddr_in *)ap_palloc((*new)->cntxt,
sizeof(struct sockaddr_in));
(*new)->addr_len = sizeof(struct sockaddr_in);
(*new)->sock = WSAAccept(sock->sock, (struct sockaddr *)(*new)->addr,
&(*new)->addr_len, NULL, 0);
if ((*new)->sock == INVALID_SOCKET) {
return errno;
}
hptr = gethostbyaddr((char *)&(*new)->addr->sin_addr,
sizeof(struct in_addr), AF_INET);
if (hptr != NULL) {
(*new)->remote_hostname = strdup(hptr->h_name);
}
ap_register_cleanup((*new)->cntxt, (void *)(*new),
socket_cleanup, NULL);
return APR_SUCCESS;
}
ap_status_t ap_connect(struct socket_t *sock, char *hostname)
{
struct hostent *hp;
int lasterror;
if ((sock->sock == INVALID_SOCKET) || (!sock->addr)) {
return APR_ENOTSOCK;
}
if (*hostname >= '0' && *hostname <= '9' &&
strspn(hostname, "0123456789.") == strlen(hostname)) {
sock->addr->sin_addr.s_addr = inet_addr(hostname);
}
else {
hp = gethostbyname(hostname);
memcpy((char *)&sock->addr->sin_addr, hp->h_addr_list[0],
hp->h_length);
sock->addr_len = sizeof(*sock->addr);
if (!hp) {
if (h_errno == TRY_AGAIN) {
return EAGAIN;
}
return h_errno;
}
}
sock->addr->sin_family = AF_INET;
if (WSAConnect(sock->sock, (const struct sockaddr *)sock->addr,
sock->addr_len,
NULL, NULL, NULL, NULL) == 0) {
sock->remote_hostname = strdup(hostname);
return APR_SUCCESS;
}
else {
lasterror = WSAGetLastError();
return APR_EEXIST;
}
}
1.1 apache-apr/apr/network_io/win32/sockopt.c
Index: sockopt.c
===================================================================
/* ====================================================================
* Copyright (c) 1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#include "networkio.h"
#include "apr_network_io.h"
#include "apr_general.h"
#include "apr_lib.h"
#include <string.h>
#include <winsock2.h>
ap_status_t soblock(SOCKET sd)
{
int one = 1;
if (ioctlsocket(sd, FIONBIO, &one) == SOCKET_ERROR) {
return APR_EEXIST;
}
return APR_SUCCESS;
}
ap_status_t sononblock(SOCKET sd)
{
int zero = 0;
if (ioctlsocket(sd, FIONBIO, &zero) == SOCKET_ERROR) {
return APR_EEXIST;
}
return APR_SUCCESS;
}
ap_status_t ap_setsocketopt(struct socket_t *sock, ap_int32_t opt, ap_int32_t
on)
{
int one;
struct linger li;
ap_status_t stat;
if (on)
one = 1;
else
one = 0;
if (opt & APR_SO_KEEPALIVE) {
if (setsockopt(sock->sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
sizeof(int)) == -1) {
return APR_EEXIST;
}
}
if (opt & APR_SO_DEBUG) {
if (setsockopt(sock->sock, SOL_SOCKET, SO_DEBUG, (void *)&one,
sizeof(int)) == -1) {
return APR_EEXIST;
}
}
if (opt & APR_SO_REUSEADDR) {
if (setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
sizeof(int)) == -1) {
return APR_EEXIST;
}
}
if (opt & APR_SO_NONBLOCK) {
if (on) {
if ((stat = soblock(sock->sock)) != APR_SUCCESS)
return stat;
}
else {
if ((stat = sononblock(sock->sock)) != APR_SUCCESS)
return stat;
}
}
if (opt & APR_SO_LINGER) {
li.l_onoff = on;
li.l_linger = MAX_SECS_TO_LINGER;
if (setsockopt(sock->sock, SOL_SOCKET, SO_LINGER, (char *) &li,
sizeof(struct linger)) == -1) {
return APR_EEXIST;
}
}
return APR_SUCCESS;
}
ap_status_t ap_gethostname(ap_context_t *cont, char *buf, int len)
{
if (gethostname(buf, len) == -1)
return APR_EEXIST;
else
return APR_SUCCESS;
}
ap_status_t ap_get_remote_hostname(struct socket_t *sock, char **name)
{
(*name) = ap_pstrdup(sock->cntxt, sock->remote_hostname);
if (*name) {
return APR_SUCCESS;
}
return APR_ENOMEM;
}