diff options
Diffstat (limited to 'util/sock.h')
| -rw-r--r-- | util/sock.h | 303 |
1 files changed, 0 insertions, 303 deletions
diff --git a/util/sock.h b/util/sock.h deleted file mode 100644 index 54dfb49..0000000 --- a/util/sock.h +++ /dev/null @@ -1,303 +0,0 @@ -// @file sock.h - -/* Copyright 2009 10gen Inc. - * - * Licensed 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. - */ - -#pragma once - -#include "../pch.h" - -#include <stdio.h> -#include <sstream> -#include "goodies.h" -#include "../db/jsobj.h" -#include "../db/cmdline.h" - -namespace mongo { - - const int SOCK_FAMILY_UNKNOWN_ERROR=13078; - string getAddrInfoStrError(int code); - -#if defined(_WIN32) - - typedef short sa_family_t; - typedef int socklen_t; - inline int getLastError() { return WSAGetLastError(); } - inline void disableNagle(int sock) { - int x = 1; - if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &x, sizeof(x)) ) - out() << "ERROR: disableNagle failed" << endl; - if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &x, sizeof(x)) ) - out() << "ERROR: SO_KEEPALIVE failed" << endl; - } - inline void prebindOptions( int sock ) { } - - // This won't actually be used on windows - struct sockaddr_un { - short sun_family; - char sun_path[108]; // length from unix header - }; - -#else - - extern CmdLine cmdLine; - -} // namespace mongo - -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <errno.h> -#include <netdb.h> -#ifdef __openbsd__ -# include <sys/uio.h> -#endif - -#ifndef AI_ADDRCONFIG -# define AI_ADDRCONFIG 0 -#endif - -namespace mongo { - - inline void closesocket(int s) { - close(s); - } - const int INVALID_SOCKET = -1; - typedef int SOCKET; - - inline void disableNagle(int sock) { - int x = 1; - -#ifdef SOL_TCP - int level = SOL_TCP; -#else - int level = SOL_SOCKET; -#endif - - if ( setsockopt(sock, level, TCP_NODELAY, (char *) &x, sizeof(x)) ) - log() << "ERROR: disableNagle failed: " << errnoWithDescription() << endl; - -#ifdef SO_KEEPALIVE - if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &x, sizeof(x)) ) - log() << "ERROR: SO_KEEPALIVE failed: " << errnoWithDescription() << endl; -#endif - - } - inline void prebindOptions( int sock ) { - DEV log() << "doing prebind option" << endl; - int x = 1; - if ( setsockopt( sock , SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) < 0 ) - out() << "Failed to set socket opt, SO_REUSEADDR" << endl; - } - - -#endif - - inline string makeUnixSockPath(int port) { - return cmdLine.socket + "/mongodb-" + BSONObjBuilder::numStr(port) + ".sock"; - } - - inline void setSockTimeouts(int sock, double secs) { - struct timeval tv; - tv.tv_sec = (int)secs; - tv.tv_usec = (int)((long long)(secs*1000*1000) % (1000*1000)); - bool report = logLevel > 3; // solaris doesn't provide these - DEV report = true; - bool ok = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(tv) ) == 0; - if( report && !ok ) log() << "unabled to set SO_RCVTIMEO" << endl; - ok = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv, sizeof(tv) ) == 0; - DEV if( report && !ok ) log() << "unabled to set SO_RCVTIMEO" << endl; - } - - // If an ip address is passed in, just return that. If a hostname is passed - // in, look up its ip and return that. Returns "" on failure. - string hostbyname(const char *hostname); - - void enableIPv6(bool state=true); - bool IPv6Enabled(); - - struct SockAddr { - SockAddr() { - addressSize = sizeof(sa); - memset(&sa, 0, sizeof(sa)); - sa.ss_family = AF_UNSPEC; - } - SockAddr(int sourcePort); /* listener side */ - SockAddr(const char *ip, int port); /* EndPoint (remote) side, or if you want to specify which interface locally */ - - template <typename T> - T& as() { return *(T*)(&sa); } - template <typename T> - const T& as() const { return *(const T*)(&sa); } - - string toString(bool includePort=true) const { - string out = getAddr(); - if (includePort && getType() != AF_UNIX && getType() != AF_UNSPEC) - out += ':' + BSONObjBuilder::numStr(getPort()); - return out; - } - - // returns one of AF_INET, AF_INET6, or AF_UNIX - sa_family_t getType() const { - return sa.ss_family; - } - - unsigned getPort() const { - switch (getType()) { - case AF_INET: return ntohs(as<sockaddr_in>().sin_port); - case AF_INET6: return ntohs(as<sockaddr_in6>().sin6_port); - case AF_UNIX: return 0; - case AF_UNSPEC: return 0; - default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return 0; - } - } - - string getAddr() const { - switch (getType()) { - case AF_INET: - case AF_INET6: { - const int buflen=128; - char buffer[buflen]; - int ret = getnameinfo(raw(), addressSize, buffer, buflen, NULL, 0, NI_NUMERICHOST); - massert(13082, getAddrInfoStrError(ret), ret == 0); - return buffer; - } - - case AF_UNIX: return (addressSize > 2 ? as<sockaddr_un>().sun_path : "anonymous unix socket"); - case AF_UNSPEC: return "(NONE)"; - default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return ""; - } - } - - bool isLocalHost() const; - - bool operator==(const SockAddr& r) const { - if (getType() != r.getType()) - return false; - - if (getPort() != r.getPort()) - return false; - - switch (getType()) { - case AF_INET: return as<sockaddr_in>().sin_addr.s_addr == r.as<sockaddr_in>().sin_addr.s_addr; - case AF_INET6: return memcmp(as<sockaddr_in6>().sin6_addr.s6_addr, r.as<sockaddr_in6>().sin6_addr.s6_addr, sizeof(in6_addr)) == 0; - case AF_UNIX: return strcmp(as<sockaddr_un>().sun_path, r.as<sockaddr_un>().sun_path) == 0; - case AF_UNSPEC: return true; // assume all unspecified addresses are the same - default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return false; - } - } - bool operator!=(const SockAddr& r) const { - return !(*this == r); - } - bool operator<(const SockAddr& r) const { - if (getType() < r.getType()) - return true; - else if (getType() > r.getType()) - return false; - - if (getPort() < r.getPort()) - return true; - else if (getPort() > r.getPort()) - return false; - - switch (getType()) { - case AF_INET: return as<sockaddr_in>().sin_addr.s_addr < r.as<sockaddr_in>().sin_addr.s_addr; - case AF_INET6: return memcmp(as<sockaddr_in6>().sin6_addr.s6_addr, r.as<sockaddr_in6>().sin6_addr.s6_addr, sizeof(in6_addr)) < 0; - case AF_UNIX: return strcmp(as<sockaddr_un>().sun_path, r.as<sockaddr_un>().sun_path) < 0; - case AF_UNSPEC: return false; - default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return false; - } - } - - const sockaddr* raw() const {return (sockaddr*)&sa;} - sockaddr* raw() {return (sockaddr*)&sa;} - - socklen_t addressSize; - private: - struct sockaddr_storage sa; - }; - - extern SockAddr unknownAddress; // ( "0.0.0.0", 0 ) - - const int MaxMTU = 16384; - - inline string getHostName() { - char buf[256]; - int ec = gethostname(buf, 127); - if ( ec || *buf == 0 ) { - log() << "can't get this server's hostname " << errnoWithDescription() << endl; - return ""; - } - return buf; - } - - string getHostNameCached(); - - class ListeningSockets { - public: - ListeningSockets() - : _mutex("ListeningSockets") - , _sockets( new set<int>() ) - , _socketPaths( new set<string>() ) - { } - void add( int sock ) { - scoped_lock lk( _mutex ); - _sockets->insert( sock ); - } - void addPath( string path ) { - scoped_lock lk( _mutex ); - _socketPaths->insert( path ); - } - void remove( int sock ) { - scoped_lock lk( _mutex ); - _sockets->erase( sock ); - } - void closeAll() { - set<int>* sockets; - set<string>* paths; - - { - scoped_lock lk( _mutex ); - sockets = _sockets; - _sockets = new set<int>(); - paths = _socketPaths; - _socketPaths = new set<string>(); - } - - for ( set<int>::iterator i=sockets->begin(); i!=sockets->end(); i++ ) { - int sock = *i; - log() << "closing listening socket: " << sock << endl; - closesocket( sock ); - } - - for ( set<string>::iterator i=paths->begin(); i!=paths->end(); i++ ) { - string path = *i; - log() << "removing socket file: " << path << endl; - ::remove( path.c_str() ); - } - } - static ListeningSockets* get(); - private: - mongo::mutex _mutex; - set<int>* _sockets; - set<string>* _socketPaths; // for unix domain sockets - static ListeningSockets* _instance; - }; - -} // namespace mongo |
