]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msgr: include my addr AND socket addr during connect handshake
authorSage Weil <sage@newdream.net>
Wed, 2 Sep 2009 21:51:55 +0000 (14:51 -0700)
committerSage Weil <sage@newdream.net>
Wed, 2 Sep 2009 23:10:05 +0000 (16:10 -0700)
This allows connecting side to detect their ip address.

src/TODO
src/msg/SimpleMessenger.cc

index 99f8e67a1108267da124746ed7506ece6bfc874a..fe7ed0181f5ddf0e47c2add540149ae5b86f2b53 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -61,6 +61,9 @@ later
 - osd failure declarations
 - rename over old files should flush data, or revert back to old contents
 
+mount.ceph
+- should look at multiple A records, pass all IPs to kernel
+
 rados
 - usage accounting
 - make rest interface superset of s3?
index f0dd2cc163235d40f93f0a0553ee378bce059661..4af974d9302fa0cf398c1f8406870229248a0559 100644 (file)
@@ -505,6 +505,23 @@ int SimpleMessenger::Pipe::accept()
     state = STATE_CLOSED;
     return -1;
   }
+
+  // and peer's socket addr (they might not know their ip)
+  entity_addr_t socket_addr;
+  socklen_t len = sizeof(socket_addr.ipaddr);
+  int r = ::getpeername(sd, (sockaddr*)&socket_addr.ipaddr, &len);
+  if (r < 0) {
+    dout(0) << "accept failed to getpeername " << errno << " " << strerror(errno) << dendl;
+    state = STATE_CLOSED;
+    return -1;
+  }
+  rc = tcp_write(sd, (char*)&socket_addr, sizeof(socket_addr));
+  if (rc < 0) {
+    dout(10) << "accept couldn't write peer addr" << dendl;
+    state = STATE_CLOSED;
+    return -1;
+  }
+
   dout(10) << "accept sd=" << sd << dendl;
   
   // identify peer
@@ -530,16 +547,11 @@ int SimpleMessenger::Pipe::accept()
   dout(10) << "accept peer addr is " << peer_addr << dendl;
   if (peer_addr.ipaddr.sin_addr.s_addr == htonl(INADDR_ANY)) {
     // peer apparently doesn't know what ip they have; figure it out for them.
-    entity_addr_t old_addr = peer_addr;
-    socklen_t len = sizeof(peer_addr.ipaddr);
-    int r = ::getpeername(sd, (sockaddr*)&peer_addr.ipaddr, &len);
-    if (r < 0) {
-      dout(0) << "accept failed to getpeername " << errno << " " << strerror(errno) << dendl;
-      state = STATE_CLOSED;
-      return -1;
-    }
-    peer_addr.ipaddr.sin_port = old_addr.ipaddr.sin_port;
-    dout(2) << "accept peer says " << old_addr << ", socket says " << peer_addr << dendl;
+    entity_addr_t was = peer_addr;
+    peer_addr.ipaddr = socket_addr.ipaddr;
+    peer_addr.ipaddr.sin_port = was.ipaddr.sin_port;
+    dout(0) << "accept peer addr is really " << peer_addr
+           << " (they said " << was << ", socket is " << socket_addr << ")" << dendl;
   }
   
   ceph_msg_connect connect;
@@ -774,6 +786,7 @@ int SimpleMessenger::Pipe::connect()
   int msglen;
   char banner[strlen(CEPH_BANNER)];
   entity_addr_t paddr;
+  entity_addr_t peer_addr_for_me, socket_addr;
 
   // create socket?
   sd = ::socket(AF_INET, SOCK_STREAM, 0);
@@ -855,8 +868,26 @@ int SimpleMessenger::Pipe::connect()
       goto fail;
     }
   }
-  
-  // identify myself
+
+  // peer addr for me
+  rc = tcp_read(sd, (char*)&peer_addr_for_me, sizeof(peer_addr_for_me));
+  if (rc < 0) {
+    dout(2) << "connect couldn't read peer addr for me, " << strerror(errno) << dendl;
+    goto fail;
+  }
+  dout(20) << "connect peer addr for me is " << peer_addr_for_me << dendl;
+
+  if (rank->need_addr) {
+    rank->lock.Lock();
+    entity_addr_t was = rank->rank_addr;
+    rank->rank_addr.ipaddr = peer_addr_for_me.ipaddr;
+    rank->rank_addr.ipaddr.sin_port = was.ipaddr.sin_port;
+    dout(0) << "rank discovered i am " << rank->rank_addr
+           << " (was " << was << ", peer says i am " << peer_addr_for_me << ")" << dendl;
+    rank->need_addr = false;
+    rank->lock.Unlock();
+  }
+
   memset(&msg, 0, sizeof(msg));
   msgvec[0].iov_base = (char*)&rank->rank_addr;
   msgvec[0].iov_len = sizeof(rank->rank_addr);