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; }