mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 09:06:21 +01:00
Make SockAddr internals support different types. SERVER-859 SERVER-866
This commit is contained in:
parent
ff23d77d07
commit
3f6871c96d
75
util/sock.h
75
util/sock.h
@ -22,7 +22,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "goodies.h"
|
#include "goodies.h"
|
||||||
|
#include "../db/jsobj.h"
|
||||||
|
|
||||||
|
#define SOCK_FAMILY_UNKNOWN_ERROR 13078
|
||||||
|
|
||||||
namespace mongo {
|
namespace mongo {
|
||||||
|
|
||||||
@ -39,6 +41,12 @@ namespace mongo {
|
|||||||
}
|
}
|
||||||
inline void prebindOptions( int sock ) {
|
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
|
#else
|
||||||
|
|
||||||
} // namespace mongo
|
} // namespace mongo
|
||||||
@ -46,6 +54,7 @@ namespace mongo {
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -112,34 +121,78 @@ namespace mongo {
|
|||||||
const T& as() const { return *(const T*)(&sa); }
|
const T& as() const { return *(const T*)(&sa); }
|
||||||
|
|
||||||
string toString(bool includePort=true) const{
|
string toString(bool includePort=true) const{
|
||||||
stringstream out;
|
string out = getAddr();
|
||||||
out << inet_ntoa(as<sockaddr_in>().sin_addr);
|
if (includePort && getType() != AF_UNIX)
|
||||||
if (includePort)
|
out += ':' + BSONObjBuilder::numStr(getPort());
|
||||||
out << ':' << ntohs(as<sockaddr_in>().sin_port);
|
return out;
|
||||||
return out.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
operator string() const{
|
operator string() const{
|
||||||
return toString();
|
return toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned getPort() {
|
// returns one of AF_INET, AF_INET6, or AF_UNIX
|
||||||
return as<sockaddr_in>().sin_port;
|
sa_family_t getType() const {
|
||||||
|
return sa.ss_family;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned getPort() const {
|
||||||
|
switch (getType()){
|
||||||
|
case AF_INET: return as<sockaddr_in>().sin_port;
|
||||||
|
case AF_INET6: return as<sockaddr_in6>().sin6_port;
|
||||||
|
case AF_UNIX: return 0;
|
||||||
|
default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string getAddr() const {
|
||||||
|
const int buflen=128;
|
||||||
|
char buffer[buflen];
|
||||||
|
|
||||||
|
switch (getType()){
|
||||||
|
case AF_INET: return inet_ntop(getType(), &as<sockaddr_in>().sin_addr, buffer, addressSize);
|
||||||
|
case AF_INET6: return inet_ntop(getType(), &as<sockaddr_in6>().sin6_addr, buffer, addressSize);
|
||||||
|
case AF_UNIX: return as<sockaddr_un>().sun_path;
|
||||||
|
default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isLocalHost() const { return inet_addr( "127.0.0.1" ) == as<sockaddr_in>().sin_addr.s_addr; }
|
bool isLocalHost() const { return inet_addr( "127.0.0.1" ) == as<sockaddr_in>().sin_addr.s_addr; }
|
||||||
|
|
||||||
bool operator==(const SockAddr& r) const {
|
bool operator==(const SockAddr& r) const {
|
||||||
return as<sockaddr_in>().sin_addr.s_addr == r.as<sockaddr_in>().sin_addr.s_addr &&
|
if (getType() != r.getType())
|
||||||
as<sockaddr_in>().sin_port == r.as<sockaddr_in>().sin_port;
|
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;
|
||||||
|
default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool operator!=(const SockAddr& r) const {
|
bool operator!=(const SockAddr& r) const {
|
||||||
return !(*this == r);
|
return !(*this == r);
|
||||||
}
|
}
|
||||||
bool operator<(const SockAddr& r) const {
|
bool operator<(const SockAddr& r) const {
|
||||||
if ( as<sockaddr_in>().sin_port >= r.as<sockaddr_in>().sin_port )
|
if (getType() < r.getType())
|
||||||
|
return true;
|
||||||
|
else if (getType() > r.getType())
|
||||||
return false;
|
return false;
|
||||||
return as<sockaddr_in>().sin_addr.s_addr < r.as<sockaddr_in>().sin_addr.s_addr;
|
|
||||||
|
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;
|
||||||
|
default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sockaddr* raw() const {return (sockaddr*)&sa;}
|
const sockaddr* raw() const {return (sockaddr*)&sa;}
|
||||||
|
Loading…
Reference in New Issue
Block a user