summaryrefslogtreecommitdiff
path: root/util/sock.h
diff options
context:
space:
mode:
Diffstat (limited to 'util/sock.h')
-rw-r--r--util/sock.h303
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