summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/db.vcproj4
-rw-r--r--db/repl/replset.cpp21
-rw-r--r--db/repl/replset.h16
-rw-r--r--util/hostandport.h75
4 files changed, 97 insertions, 19 deletions
diff --git a/db/db.vcproj b/db/db.vcproj
index 6e79cf0cab7..78114a846e3 100644
--- a/db/db.vcproj
+++ b/db/db.vcproj
@@ -1905,6 +1905,10 @@
>
</File>
<File
+ RelativePath="..\util\hostandport.h"
+ >
+ </File>
+ <File
RelativePath=".\repl\replset.cpp"
>
</File>
diff --git a/db/repl/replset.cpp b/db/repl/replset.cpp
index 65c006d79e5..8044dc0d0d8 100644
--- a/db/repl/replset.cpp
+++ b/db/repl/replset.cpp
@@ -17,38 +17,47 @@
#include "stdafx.h"
#include "../cmdline.h"
#include "replset.h"
+#include "../../util/sock.h"
namespace mongo {
ReplSet *theReplSet = 0;
ReplSet::ReplSet(string cfgString) {
+ cmdLine.port;
+
const char *p = cfgString.c_str();
const char *q = strchr(p, '/');
uassert(13093, "bad --replset config string format is: <setname>/<seedhost1>,<seedhost2>[,...]", q != 0 && p != q);
_name = string(p, q-p);
- set<RemoteServer> temp;
- vector<RemoteServer> *seeds = new vector<RemoteServer>;
+ set<HostAndPort> temp;
+ vector<HostAndPort> *seeds = new vector<HostAndPort>;
while( 1 ) {
p = q + 1;
q = strchr(p, ',');
if( q == 0 ) q = strchr(p,0);
uassert(13094, "bad --replset config string", p != q);
const char *colon = strchr(p, ':');
- RemoteServer m;
+ HostAndPort m;
if( colon && colon < q ) {
int port = atoi(colon+1);
uassert(13095, "bad --replset port #", port > 0);
- m = RemoteServer(string(p,colon-p),port);
+ m = HostAndPort(string(p,colon-p),port);
}
else {
// no port specified.
- m = RemoteServer(string(p,q-p));
+ m = HostAndPort(string(p,q-p));
}
uassert(13096, "bad --replset config string - dups?", temp.count(m) == 0 ); // these uasserts leak seeds but that's ok
temp.insert(m);
- seeds->push_back(m);
+
+ uassert(10000, "can't use localhost in replset host list", !m.isLocalHost());
+
+ if( m.isSelf() )
+ log() << "replSet: ignoring seed " << m.toString() << " (=self)" << endl;
+ else
+ seeds->push_back(m);
if( *q == 0 )
break;
}
diff --git a/db/repl/replset.h b/db/repl/replset.h
index 88e9112b8c4..f2c5ebeab13 100644
--- a/db/repl/replset.h
+++ b/db/repl/replset.h
@@ -19,21 +19,11 @@
#pragma once
#include "../../util/concurrency/list.h"
+#include "../../util/hostandport.h"
namespace mongo {
- class ReplSet;
- extern ReplSet *theReplSet;
-
- struct RemoteServer {
- RemoteServer() : _port(-1) { }
- RemoteServer(string h, int p = -1) : _host(h), _port(p) { }
- bool operator<(const RemoteServer& r) const { return _host < r._host || (_host==r._host&&_port<r._port); }
- private:
- // invariant (except full obj assignment):
- string _host;
- int _port;
- };
+ extern class ReplSet *theReplSet;
/* information about the entire repl set, such as the various servers in the set, and their state */
/* note: We currently do not free mem when the set goes away - it is assumed the replset is a
@@ -51,7 +41,7 @@ namespace mongo {
private:
string _name;
- const vector<RemoteServer> *_seeds;
+ const vector<HostAndPort> *_seeds;
struct MemberInfo : public List1<MemberInfo>::Base {
MemberInfo() : dead(false), lastHeartbeat(0) { }
diff --git a/util/hostandport.h b/util/hostandport.h
new file mode 100644
index 00000000000..f3f6cc3a26f
--- /dev/null
+++ b/util/hostandport.h
@@ -0,0 +1,75 @@
+// hostandport.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 "sock.h"
+#include "../db/cmdline.h"
+
+namespace mongo {
+
+ /** helper for manipulating host:port connection endpoints.
+ */
+ struct HostAndPort {
+ HostAndPort() : _port(-1) { }
+
+ HostAndPort(string h, int p = -1) : _host(h), _port(p) { }
+
+ bool operator<(const HostAndPort& r) const { return _host < r._host || (_host==r._host&&_port<r._port); }
+
+ /* returns true if the host/port combo identifies this process instance. */
+ bool isSelf() const;
+
+ bool isLocalHost() const;
+
+ string toString();
+ private:
+ // invariant (except full obj assignment):
+ string _host;
+ int _port;
+ };
+
+ /** returns true if strings share a common starting prefix */
+ inline bool sameStart(const char *p, const char *q) {
+ while( 1 ) {
+ if( *p == 0 || *q == 0 )
+ return true;
+ if( *p != *q )
+ break;
+ p++; q++;
+ }
+ return false;
+ }
+
+ inline bool HostAndPort::isSelf() const {
+ if( _port != cmdLine.port )
+ return false;
+ assert( _host != "localhost" && _host != "127.0.0.1" );
+ return sameStart(getHostName().c_str(), _host.c_str());
+ }
+
+ inline string HostAndPort::toString() {
+ stringstream ss;
+ ss << _host << ':' << _port;
+ return ss.str();
+ }
+
+ inline bool HostAndPort::isLocalHost() const {
+ return _host == "localhost" || _host == "127.0.0.1";
+ }
+
+}