summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/sys/windows/Socket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/qpid/sys/windows/Socket.cpp')
-rwxr-xr-xcpp/src/qpid/sys/windows/Socket.cpp348
1 files changed, 0 insertions, 348 deletions
diff --git a/cpp/src/qpid/sys/windows/Socket.cpp b/cpp/src/qpid/sys/windows/Socket.cpp
deleted file mode 100755
index 2ce274acc9..0000000000
--- a/cpp/src/qpid/sys/windows/Socket.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-// Ensure we get all of winsock2.h
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/SocketAddress.h"
-#include "qpid/sys/windows/IoHandlePrivate.h"
-#include "qpid/sys/windows/check.h"
-#include "qpid/sys/Time.h"
-
-#include <cstdlib>
-#include <string.h>
-
-#include <winsock2.h>
-
-#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
-
-// Need to initialize WinSock. Ideally, this would be a singleton or embedded
-// in some one-time initialization function. I tried boost singleton and could
-// not get it to compile (and others located in google had the same problem).
-// So, this simple static with an interlocked increment will do for known
-// use cases at this time. Since this will only shut down winsock at process
-// termination, there may be some problems with client programs that also
-// expect to load and unload winsock, but we'll see...
-// If someone does get an easy-to-use singleton sometime, converting to it
-// may be preferable.
-
-namespace {
-
-static LONG volatile initialized = 0;
-
-class WinSockSetup {
- // : public boost::details::pool::singleton_default<WinSockSetup> {
-
-public:
- WinSockSetup() {
- LONG timesEntered = InterlockedIncrement(&initialized);
- if (timesEntered > 1)
- return;
- err = 0;
- WORD wVersionRequested;
- WSADATA wsaData;
-
- /* Request WinSock 2.2 */
- wVersionRequested = MAKEWORD(2, 2);
- err = WSAStartup(wVersionRequested, &wsaData);
- }
-
- ~WinSockSetup() {
- WSACleanup();
- }
-
-public:
- int error(void) const { return err; }
-
-protected:
- DWORD err;
-};
-
-static WinSockSetup setup;
-
-} /* namespace */
-
-namespace qpid {
-namespace sys {
-
-namespace {
-
-std::string getName(SOCKET fd, bool local, bool includeService = false)
-{
- sockaddr_in name; // big enough for any socket address
- socklen_t namelen = sizeof(name);
- if (local) {
- QPID_WINSOCK_CHECK(::getsockname(fd, (sockaddr*)&name, &namelen));
- } else {
- QPID_WINSOCK_CHECK(::getpeername(fd, (sockaddr*)&name, &namelen));
- }
-
- char servName[NI_MAXSERV];
- char dispName[NI_MAXHOST];
- if (includeService) {
- if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return std::string(dispName) + ":" + std::string(servName);
- } else {
- if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- dispName, sizeof(dispName),
- 0, 0,
- NI_NUMERICHOST) != 0)
- throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return dispName;
- }
-}
-
-std::string getService(SOCKET fd, bool local)
-{
- sockaddr_in name; // big enough for any socket address
- socklen_t namelen = sizeof(name);
-
- if (local) {
- QPID_WINSOCK_CHECK(::getsockname(fd, (sockaddr*)&name, &namelen));
- } else {
- QPID_WINSOCK_CHECK(::getpeername(fd, (sockaddr*)&name, &namelen));
- }
-
- char servName[NI_MAXSERV];
- if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- 0, 0,
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return servName;
-}
-} // namespace
-
-Socket::Socket() :
- IOHandle(new IOHandlePrivate),
- nonblocking(false),
- nodelay(false)
-{
- SOCKET& socket = impl->fd;
- if (socket != INVALID_SOCKET) Socket::close();
- SOCKET s = ::socket (PF_INET, SOCK_STREAM, 0);
- if (s == INVALID_SOCKET) throw QPID_WINDOWS_ERROR(WSAGetLastError());
- socket = s;
-}
-
-Socket::Socket(IOHandlePrivate* h) :
- IOHandle(h),
- nonblocking(false),
- nodelay(false)
-{}
-
-void
-Socket::createSocket(const SocketAddress& sa) const
-{
- SOCKET& socket = impl->fd;
- if (socket != INVALID_SOCKET) Socket::close();
-
- SOCKET s = ::socket (getAddrInfo(sa).ai_family,
- getAddrInfo(sa).ai_socktype,
- 0);
- if (s == INVALID_SOCKET) throw QPID_WINDOWS_ERROR(WSAGetLastError());
- socket = s;
-
- try {
- if (nonblocking) setNonblocking();
- if (nodelay) setTcpNoDelay();
- } catch (std::exception&) {
- closesocket(s);
- socket = INVALID_SOCKET;
- throw;
- }
-}
-
-void Socket::setTimeout(const Duration& interval) const
-{
- const SOCKET& socket = impl->fd;
- int64_t nanosecs = interval;
- nanosecs /= (1000 * 1000); // nsecs -> usec -> msec
- int msec = 0;
- if (nanosecs > std::numeric_limits<int>::max())
- msec = std::numeric_limits<int>::max();
- else
- msec = static_cast<int>(nanosecs);
- setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&msec, sizeof(msec));
- setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&msec, sizeof(msec));
-}
-
-void Socket::setNonblocking() const {
- u_long nonblock = 1;
- QPID_WINSOCK_CHECK(ioctlsocket(impl->fd, FIONBIO, &nonblock));
-}
-
-void Socket::connect(const std::string& host, uint16_t port) const
-{
- SocketAddress sa(host, boost::lexical_cast<std::string>(port));
- connect(sa);
-}
-
-void
-Socket::connect(const SocketAddress& addr) const
-{
- const SOCKET& socket = impl->fd;
- const addrinfo *addrs = &(getAddrInfo(addr));
- int error = 0;
- WSASetLastError(0);
- while (addrs != 0) {
- if ((::connect(socket, addrs->ai_addr, addrs->ai_addrlen) == 0) ||
- (WSAGetLastError() == WSAEWOULDBLOCK))
- break;
- // Error... save this error code and see if there are other address
- // to try before throwing the exception.
- error = WSAGetLastError();
- addrs = addrs->ai_next;
- }
- if (error)
- throw qpid::Exception(QPID_MSG(strError(error) << ": " << connectname));
-}
-
-void
-Socket::close() const
-{
- SOCKET& socket = impl->fd;
- if (socket == INVALID_SOCKET) return;
- QPID_WINSOCK_CHECK(closesocket(socket));
- socket = INVALID_SOCKET;
-}
-
-
-int Socket::write(const void *buf, size_t count) const
-{
- const SOCKET& socket = impl->fd;
- int sent = ::send(socket, (const char *)buf, count, 0);
- if (sent == SOCKET_ERROR)
- return -1;
- return sent;
-}
-
-int Socket::read(void *buf, size_t count) const
-{
- const SOCKET& socket = impl->fd;
- int received = ::recv(socket, (char *)buf, count, 0);
- if (received == SOCKET_ERROR)
- return -1;
- return received;
-}
-
-int Socket::listen(uint16_t port, int backlog) const
-{
- const SOCKET& socket = impl->fd;
- BOOL yes=1;
- QPID_WINSOCK_CHECK(setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)));
- struct sockaddr_in name;
- memset(&name, 0, sizeof(name));
- name.sin_family = AF_INET;
- name.sin_port = htons(port);
- name.sin_addr.s_addr = 0;
- if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) == SOCKET_ERROR)
- throw Exception(QPID_MSG("Can't bind to port " << port << ": " << strError(WSAGetLastError())));
- if (::listen(socket, backlog) == SOCKET_ERROR)
- throw Exception(QPID_MSG("Can't listen on port " << port << ": " << strError(WSAGetLastError())));
-
- socklen_t namelen = sizeof(name);
- QPID_WINSOCK_CHECK(::getsockname(socket, (struct sockaddr*)&name, &namelen));
- return ntohs(name.sin_port);
-}
-
-Socket* Socket::accept() const
-{
- SOCKET afd = ::accept(impl->fd, 0, 0);
- if (afd != INVALID_SOCKET)
- return new Socket(new IOHandlePrivate(afd));
- else if (WSAGetLastError() == EAGAIN)
- return 0;
- else throw QPID_WINDOWS_ERROR(WSAGetLastError());
-}
-
-std::string Socket::getSockname() const
-{
- return getName(impl->fd, true);
-}
-
-std::string Socket::getPeername() const
-{
- return getName(impl->fd, false);
-}
-
-std::string Socket::getPeerAddress() const
-{
- if (!connectname.empty())
- return std::string (connectname);
- return getName(impl->fd, false, true);
-}
-
-std::string Socket::getLocalAddress() const
-{
- return getName(impl->fd, true, true);
-}
-
-uint16_t Socket::getLocalPort() const
-{
- return atoi(getService(impl->fd, true).c_str());
-}
-
-uint16_t Socket::getRemotePort() const
-{
- return atoi(getService(impl->fd, true).c_str());
-}
-
-int Socket::getError() const
-{
- int result;
- socklen_t rSize = sizeof (result);
-
- QPID_WINSOCK_CHECK(::getsockopt(impl->fd, SOL_SOCKET, SO_ERROR, (char *)&result, &rSize));
- return result;
-}
-
-void Socket::setTcpNoDelay() const
-{
- int flag = 1;
- int result = setsockopt(impl->fd,
- IPPROTO_TCP,
- TCP_NODELAY,
- (char *)&flag,
- sizeof(flag));
- QPID_WINSOCK_CHECK(result);
- nodelay = true;
-}
-
-inline IOHandlePrivate* IOHandlePrivate::getImpl(const qpid::sys::IOHandle &h)
-{
- return h.impl;
-}
-
-SOCKET toSocketHandle(const Socket& s)
-{
- return IOHandlePrivate::getImpl(s)->fd;
-}
-
-}} // namespace qpid::sys