OW_ServerSocketImpl.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #include "OW_config.h"
00037 #include "OW_ServerSocketImpl.hpp"
00038 #include "OW_Format.hpp"
00039 #include "OW_ByteSwap.hpp"
00040 #include "OW_FileSystem.hpp"
00041 #include "OW_File.hpp"
00042 #include "OW_Thread.hpp"
00043 #include "OW_SocketUtils.hpp"
00044 #include "OW_System.hpp"
00045 
00046 extern "C"
00047 {
00048 #if !defined(OW_WIN32)
00049 #include <sys/types.h>
00050 #include <sys/stat.h>
00051 #include <sys/socket.h>
00052 #include <sys/time.h>
00053 #include <netinet/in.h>
00054 #include <arpa/inet.h>
00055 #include <netdb.h>
00056 #include <unistd.h>
00057 #include <fcntl.h>
00058 #endif
00059 }
00060 
00061 #include <cerrno>
00062 
00063 namespace OW_NAMESPACE
00064 {
00066 ServerSocketImpl::ServerSocketImpl(SSLServerCtxRef sslCtx)
00067    : m_sockfd(-1)
00068    , m_localAddress(SocketAddress::allocEmptyAddress(SocketAddress::INET))
00069    , m_isActive(false)
00070    , m_sslCtx(sslCtx)
00071 #if defined(OW_WIN32)
00072    , m_event(NULL)
00073    , m_shuttingDown(false)
00074 {
00075    m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
00076    OW_ASSERT(m_event != NULL);
00077 }
00078 #else
00079    , m_udsFile()
00080 {
00081 }
00082 #endif
00083 
00085 ServerSocketImpl::ServerSocketImpl(SocketFlags::ESSLFlag isSSL)
00086    : m_sockfd(-1)
00087    , m_localAddress(SocketAddress::allocEmptyAddress(SocketAddress::INET))
00088    , m_isActive(false)
00089    , m_isSSL(isSSL)
00090 #if defined(OW_WIN32)
00091    , m_event(NULL)
00092    , m_shuttingDown(false)
00093 {
00094    m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
00095    OW_ASSERT(m_event != NULL);
00096 }
00097 #else
00098    , m_udsFile()
00099 {
00100 }
00101 #endif
00102 
00104 ServerSocketImpl::~ServerSocketImpl()
00105 {
00106    try
00107    {
00108       close();
00109    }
00110    catch (...)
00111    {
00112       // don't let exceptions escape
00113    }
00114 #if defined(OW_WIN32)
00115    ::CloseHandle(m_event);
00116 #endif
00117 }
00118 
00120 Select_t
00121 ServerSocketImpl::getSelectObj() const
00122 {
00123 #if defined(OW_WIN32)
00124    Select_t st;
00125    st.event = m_event;
00126    st.sockfd = m_sockfd;
00127    st.networkevents = FD_ACCEPT;
00128    return st;
00129 #else
00130    return m_sockfd;
00131 #endif
00132 }
00133 
00135 void
00136 ServerSocketImpl::doListen(UInt16 port, SocketFlags::ESSLFlag isSSL,
00137    int queueSize, const String& listenAddr,
00138    SocketFlags::EReuseAddrFlag reuseAddr)
00139 {
00140    m_isSSL = isSSL;
00141    doListen(port, queueSize,listenAddr, reuseAddr);
00142 }
00143 
00144 #if defined(OW_WIN32)
00145 
00146 void
00147 ServerSocketImpl::doListen(UInt16 port,
00148    int queueSize, const String& listenAddr,
00149    SocketFlags::EReuseAddrFlag reuseAddr)
00150 {
00151    m_localAddress = SocketAddress::allocEmptyAddress(SocketAddress::INET);
00152    close();
00153    if ((m_sockfd = ::socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
00154    {
00155       OW_THROW(SocketException, Format("ServerSocketImpl: %1",
00156          System::lastErrorMsg(true)).c_str());
00157    }
00158 
00159    // Set listen socket to nonblocking
00160    unsigned long cmdArg = 1;
00161    if (::ioctlsocket(m_sockfd, FIONBIO, &cmdArg) == SOCKET_ERROR)
00162    {
00163       OW_THROW(SocketException, Format("ServerSocketImpl: %1",
00164          System::lastErrorMsg(true)).c_str());
00165    }
00166 
00167    if (reuseAddr)
00168    {
00169       DWORD reuse = 1;
00170       ::setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR,
00171          (const char*)&reuse, sizeof(reuse));
00172    }
00173       
00174    InetSocketAddress_t inetAddr;
00175    inetAddr.sin_family = AF_INET;
00176    if (listenAddr == SocketAddress::ALL_LOCAL_ADDRESSES)
00177    {
00178       inetAddr.sin_addr.s_addr = hton32(INADDR_ANY);
00179    }
00180    else
00181    {
00182       SocketAddress addr = SocketAddress::getByName(listenAddr);
00183       inetAddr.sin_addr.s_addr = addr.getInetAddress()->sin_addr.s_addr;
00184    }
00185    inetAddr.sin_port = hton16(port);
00186    if (::bind(m_sockfd, reinterpret_cast<sockaddr*>(&inetAddr), sizeof(inetAddr)) == -1)
00187    {
00188       close();
00189       OW_THROW(SocketException, Format("ServerSocketImpl: %1",
00190          System::lastErrorMsg(true)).c_str());
00191    }
00192    if (::listen(m_sockfd, queueSize) == -1)
00193    {
00194       close();
00195       OW_THROW(SocketException, Format("ServerSocketImpl: %1",
00196          System::lastErrorMsg(true)).c_str());
00197    }
00198    fillAddrParms();
00199    m_isActive = true;
00200 }
00201 
00202 namespace
00203 {
00204 
00205 int
00206 waitForAcceptIO(SocketHandle_t fd, HANDLE eventArg, int timeOutSecs,
00207    long networkEvents)
00208 {
00209    DWORD timeout = (timeOutSecs != -1)
00210       ? static_cast<DWORD>(timeOutSecs * 1000)
00211       : INFINITE;
00212 
00213    if (networkEvents != -1L)
00214    {
00215       if(::WSAEventSelect(fd, eventArg, networkEvents) != 0)
00216       {
00217          OW_THROW(SocketException,
00218             Format("WSAEventSelect failed in waitForAcceptIO: %1",
00219             System::lastErrorMsg(true)).c_str());
00220       }
00221    }
00222 
00223    int cc;
00224    switch(::WaitForSingleObject(eventArg, timeout))
00225    {
00226       case WAIT_OBJECT_0:
00227          ::ResetEvent(eventArg);
00228          cc = 0;
00229          break;
00230       case WAIT_TIMEOUT:
00231          cc = ETIMEDOUT;
00232          break;
00233       default:
00234          cc = -1;
00235          break;
00236    }
00237 
00238    return cc;
00239 }
00240 
00241 }
00242 
00244 Socket
00245 ServerSocketImpl::accept(int timeoutSecs)
00246 {
00247    OW_ASSERT(m_localAddress.getType() == SocketAddress::INET);
00248 
00249    if (!m_isActive)
00250    {
00251       OW_THROW(SocketException, "ServerSocketImpl::accept: NONE");
00252    }
00253 
00254    // Register interest in FD_ACCEPT events
00255    if(::WSAEventSelect(m_sockfd, m_event, FD_ACCEPT) != 0)
00256    {
00257       OW_THROW(SocketException,
00258          Format("WSAEventSelect failed in accept: %1",
00259          System::lastErrorMsg(true)).c_str());
00260    }
00261 
00262    SOCKET clntfd;
00263    socklen_t clntlen;
00264    struct sockaddr_in clntInetAddr;
00265    HANDLE events[2];
00266    int cc;
00267 
00268    while (true)
00269    {
00270       clntlen = sizeof(clntInetAddr);
00271       clntfd = ::accept(m_sockfd,
00272          reinterpret_cast<struct sockaddr*>(&clntInetAddr), &clntlen);
00273       if (clntfd != INVALID_SOCKET)
00274       {
00275          // Got immediate connection
00276          break;
00277       }
00278 
00279       if (::WSAGetLastError() != WSAEWOULDBLOCK)
00280       {
00281          OW_THROW(SocketException, Format("ServerSocketImpl: %1",
00282             System::lastErrorMsg(true)).c_str());
00283       }
00284 
00285       //cc = SocketUtils::waitForIO(m_sockfd, m_event, INFINITE, FD_ACCEPT);
00286       cc = waitForAcceptIO(m_sockfd, m_event, timeoutSecs, FD_ACCEPT);
00287       if(m_shuttingDown)
00288       {
00289          cc = -2;
00290       }
00291 
00292       switch (cc)
00293       {
00294          case -1:
00295             OW_THROW(SocketException, "Error while waiting for network events");
00296          case -2:
00297             OW_THROW(SocketException, "Shutdown event was signaled");
00298          case ETIMEDOUT:
00299             OW_THROW(SocketTimeoutException,"Timed out waiting for a connection");
00300       }
00301    }
00302 
00303    // Unregister for any events.  necessary to put us back in blocking mode.
00304    if(::WSAEventSelect(clntfd, NULL, 0) != 0)
00305    {
00306       OW_THROW(SocketException,
00307          Format("WSAEventSelect failed in accept: %1",
00308          System::lastErrorMsg(true)).c_str());
00309    }
00310 
00311    // set socket back to blocking; otherwise it'll inherit non-blocking from the listening socket
00312    unsigned long cmdArg = 0;
00313    if (::ioctlsocket(clntfd, FIONBIO, &cmdArg) == SOCKET_ERROR)
00314    {
00315       OW_THROW(SocketException, Format("ServerSocketImpl: %1",
00316          System::lastErrorMsg(true)).c_str());
00317    }
00318 
00319    if (!m_sslCtx && m_isSSL == SocketFlags::E_SSL)
00320    {
00321       return Socket(clntfd, m_localAddress.getType(), m_isSSL);
00322    }
00323 
00324    return Socket(clntfd, m_localAddress.getType(), m_sslCtx);
00325 }
00326 #else
00327 
00328 void
00329 ServerSocketImpl::doListen(UInt16 port,
00330    int queueSize, const String& listenAddr,
00331    SocketFlags::EReuseAddrFlag reuseAddr)
00332 {
00333    m_localAddress = SocketAddress::allocEmptyAddress(SocketAddress::INET);
00334    close();
00335    if ((m_sockfd = ::socket(AF_INET, SOCK_STREAM, 0)) == -1)
00336    {
00337       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): socket()");
00338    }
00339    // set the close on exec flag so child process can't keep the socket.
00340    if (::fcntl(m_sockfd, F_SETFD, FD_CLOEXEC) == -1)
00341    {
00342       close();
00343       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): fcntl() failed to set "
00344          "close-on-exec flag on listen socket");
00345    }
00346    // set listen socket to nonblocking; see Unix Network Programming,
00347    // pages 422-424.
00348    int fdflags = ::fcntl(m_sockfd, F_GETFL, 0);
00349    ::fcntl(m_sockfd, F_SETFL, fdflags | O_NONBLOCK);
00350    // is this safe? Should be, but some OS kernels have problems with it.
00351    // It's OK on current linux versions.  Definitely not on
00352    // OLD (kernel < 1.3.60) ones.  Who knows about on other OS's like UnixWare or
00353    // OpenServer?
00354    // See http://monkey.org/openbsd/archive/misc/9601/msg00031.html
00355    // or just google for "bind() Security Problems"
00356    // Let the kernel reuse the port without waiting for it to time out.
00357    // Without this line, you can't stop and immediately re-start the daemon.
00358    if (reuseAddr)
00359    {
00360       int reuse = 1;
00361       ::setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
00362    }
00363       
00364    InetSocketAddress_t inetAddr;
00365    inetAddr.sin_family = AF_INET;
00366    if (listenAddr == SocketAddress::ALL_LOCAL_ADDRESSES)
00367    {
00368       inetAddr.sin_addr.s_addr = hton32(INADDR_ANY);
00369    }
00370    else
00371    {
00372       SocketAddress addr = SocketAddress::getByName(listenAddr);
00373       inetAddr.sin_addr.s_addr = addr.getInetAddress()->sin_addr.s_addr;
00374    }
00375    inetAddr.sin_port = hton16(port);
00376    if (::bind(m_sockfd, reinterpret_cast<sockaddr*>(&inetAddr), sizeof(inetAddr)) == -1)
00377    {
00378       close();
00379       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): bind");
00380    }
00381    if (::listen(m_sockfd, queueSize) == -1)
00382    {
00383       close();
00384       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): listen");
00385    }
00386    fillAddrParms();
00387    m_isActive = true;
00388 }
00389 
00391 void
00392 ServerSocketImpl::doListen(const String& filename, int queueSize, bool reuseAddr)
00393 {
00394    m_localAddress = SocketAddress::getUDS(filename);
00395    close();
00396    if ((m_sockfd = ::socket(PF_UNIX,SOCK_STREAM, 0)) == -1)
00397    {
00398       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): socket()");
00399    }
00400    // set the close on exec flag so child process can't keep the socket.
00401    if (::fcntl(m_sockfd, F_SETFD, FD_CLOEXEC) == -1)
00402    {
00403       close();
00404       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): fcntl() failed to set "
00405          "close-on-exec flag on listen socket");
00406    }
00407 
00408    // set listen socket to nonblocking; see Unix Network Programming,
00409    // pages 422-424.
00410    int fdflags = ::fcntl(m_sockfd, F_GETFL, 0);
00411    ::fcntl(m_sockfd, F_SETFL, fdflags | O_NONBLOCK);
00412    
00413    if (reuseAddr)
00414    {
00415       // Let the kernel reuse the port without waiting for it to time out.
00416       // Without this line, you can't stop and immediately re-start the daemon.
00417       int reuse = 1;
00418       ::setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
00419    }
00420    String lockfilename = filename + ".lock";
00421    m_udsFile = FileSystem::openOrCreateFile(lockfilename);
00422    if (!m_udsFile)
00423    {
00424       OW_THROW_ERRNO_MSG(SocketException,
00425          Format("ServerSocketImpl::doListen(): Unable to open or create Unix Domain Socket lock: %1",
00426             lockfilename).c_str());
00427    }
00428    // if we can't get a lock, someone else has got it open.
00429    if (m_udsFile.tryLock() == -1)
00430    {
00431       OW_THROW_ERRNO_MSG(SocketException,
00432          Format("ServerSocketImpl::doListen(): Unable to lock Unix Domain Socket: %1",
00433             filename).c_str());
00434    }
00435    // We got the lock, so clobber the UDS if it's there so bind will succeed.
00436    // If it's not gone, bind will fail.
00437    if (FileSystem::exists(filename))
00438    {
00439       if (!FileSystem::removeFile(filename.c_str()))
00440       {
00441          OW_THROW_ERRNO_MSG(SocketException,
00442             Format("ServerSocketImpl::doListen(): Unable to unlink Unix Domain Socket: %1",
00443                filename).c_str());
00444       }
00445    }
00446       
00447    if (::bind(m_sockfd, m_localAddress.getNativeForm(),
00448       m_localAddress.getNativeFormSize()) == -1)
00449    {
00450       close();
00451       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): bind()");
00452    }
00453    // give anybody access to the socket
00454    // unfortunately, fchmod() doesn't work on a UDS
00455    if (::chmod(filename.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == -1)
00456    {
00457       close();
00458       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): chmod()");
00459    }
00460    if (::listen(m_sockfd, queueSize) == -1)
00461    {
00462       close();
00463       OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::doListen(): listen()");
00464    }
00465    fillAddrParms();
00466    m_isActive = true;
00467 }
00469 bool
00470 ServerSocketImpl::waitForIO(int fd, int timeOutSecs,
00471    SocketFlags::EWaitDirectionFlag forInput)
00472 {
00473    return SocketUtils::waitForIO(fd, timeOutSecs, forInput) == 0;
00474 }
00476 /*
00477 String
00478 ServerSocketImpl::addrString()
00479 {
00480    return inetAddrToString(m_localAddress, m_localPort);
00481 }
00482 */
00484 Socket
00485 ServerSocketImpl::accept(int timeoutSecs)
00486 {
00487    if (!m_isActive)
00488    {
00489       OW_THROW(SocketException, "ServerSocketImpl::accept(): m_isActive == false");
00490    }
00491    if (SocketUtils::waitForIO(m_sockfd, timeoutSecs, SocketFlags::E_WAIT_FOR_INPUT) == 0)
00492    {
00493       int clntfd;
00494       socklen_t clntlen;
00495       struct sockaddr_in clntInetAddr;
00496       struct sockaddr_un clntUnixAddr;
00497       struct sockaddr* pSA(0);
00498       if (m_localAddress.getType() == SocketAddress::INET)
00499       {
00500          pSA = reinterpret_cast<struct sockaddr*>(&clntInetAddr);
00501          clntlen = sizeof(clntInetAddr);
00502       }
00503       else if (m_localAddress.getType() == SocketAddress::UDS)
00504       {
00505          pSA = reinterpret_cast<struct sockaddr*>(&clntUnixAddr);
00506          clntlen = sizeof(clntUnixAddr);
00507       }
00508       else
00509       {
00510          OW_ASSERT(0);
00511       }
00512       
00513       clntfd = ::accept(m_sockfd, pSA, &clntlen);
00514       if (clntfd < 0)
00515       {
00516          // check to see if client aborts connection between select and accept.
00517          // see Unix Network Programming pages 422-424.
00518          if (errno == EWOULDBLOCK
00519              || errno == ECONNABORTED
00520 #ifdef EPROTO
00521              || errno == EPROTO
00522 #endif
00523             )
00524          {
00525             OW_THROW(SocketException, "Client aborted TCP connection "
00526                "between select() and accept()");
00527          }
00528       
00529          if (errno == EINTR)
00530          {
00531             Thread::testCancel();
00532          }
00533          OW_THROW_ERRNO_MSG(SocketException, "ServerSocketImpl::accept(): accept()");
00534       }
00535       // set socket back to blocking; see Unix Network Programming,
00536       // pages 422-424.
00537       int fdflags = ::fcntl(clntfd, F_GETFL, 0);
00538       // On most OSs non-blocking is inherited from the listen socket,
00539       // but it's not on Openserver.
00540       if ((fdflags & O_NONBLOCK) == O_NONBLOCK)
00541       {
00542          ::fcntl(clntfd, F_SETFL, fdflags ^ O_NONBLOCK);
00543       }
00544       // TODO, how to make this bw compatible?
00545       //return Socket(clntfd, m_localAddress.getType(), m_isSSL);
00546       if (!m_sslCtx && m_isSSL == SocketFlags::E_SSL)
00547       {
00548          return Socket(clntfd, m_localAddress.getType(), m_isSSL); // for bw compat.
00549       }
00550       return Socket(clntfd, m_localAddress.getType(), m_sslCtx);
00551    }
00552    else
00553    {
00554       // The timeout expired.
00555       OW_THROW(SocketTimeoutException,"Timed out waiting for a connection");
00556    }
00557 }
00558 #endif
00559 
00561 void
00562 ServerSocketImpl::close()
00563 {
00564    if (m_isActive)
00565    {
00566 #if defined(OW_WIN32)
00567       ::closesocket(m_sockfd);
00568       m_sockfd = INVALID_SOCKET;
00569 #else
00570 		::close(m_sockfd);
00571       if (m_localAddress.getType() == SocketAddress::UDS)
00572       {
00573          String filename = m_localAddress.toString();
00574          if (!FileSystem::removeFile(filename.c_str()))
00575          {
00576             OW_THROW_ERRNO_MSG(SocketException,
00577                Format("ServerSocketImpl::close(): Unable to unlink Unix Domain Socket: %1",
00578                   filename).c_str());
00579          }
00580          if (m_udsFile)
00581          {
00582             String lockfilename = filename + ".lock";
00583             if (m_udsFile.unlock() == -1)
00584             {
00585                OW_THROW_ERRNO_MSG(SocketException,
00586                   Format("ServerSocketImpl::close(): Failed to unlock Unix Domain Socket: %1",
00587                      lockfilename).c_str());
00588             }
00589             m_udsFile.close();
00590             if (!FileSystem::removeFile(lockfilename.c_str()))
00591             {
00592                OW_THROW_ERRNO_MSG(SocketException,
00593                   Format("ServerSocketImpl::close(): Unable to unlink Unix Domain Socket lock: %1",
00594                      lockfilename).c_str());
00595             }
00596          }
00597       }
00598 #endif
00599       m_isActive = false;
00600    }
00601 }
00603 void
00604 ServerSocketImpl::fillAddrParms()
00605 {
00606    socklen_t len;
00607    if (m_localAddress.getType() == SocketAddress::INET)
00608    {
00609       struct sockaddr_in addr;
00610       memset(&addr, 0, sizeof(addr));
00611       len = sizeof(addr);
00612       if (getsockname(m_sockfd, reinterpret_cast<struct sockaddr*>(&addr), &len) == -1)
00613       {
00614          OW_THROW_ERRNO_MSG(SocketException, "SocketImpl::fillAddrParms(): getsockname");
00615       }
00616       m_localAddress.assignFromNativeForm(&addr, len);
00617    }
00618 #if !defined(OW_WIN32)
00619    else if (m_localAddress.getType() == SocketAddress::UDS)
00620    {
00621       struct sockaddr_un addr;
00622       memset(&addr, 0, sizeof(addr));
00623       len = sizeof(addr);
00624       if (getsockname(m_sockfd, reinterpret_cast<struct sockaddr*>(&addr), &len) == -1)
00625       {
00626          OW_THROW_ERRNO_MSG(SocketException, "SocketImpl::fillAddrParms(): getsockname");
00627       }
00628       m_localAddress.assignFromNativeForm(&addr, len);
00629    }
00630 #endif
00631    else
00632    {
00633       OW_ASSERT(0);
00634    }
00635 }
00636 
00637 } // end namespace OW_NAMESPACE
00638 

Generated on Thu Feb 9 08:48:10 2006 for openwbem by  doxygen 1.4.6