Example #1
0
/**
 * Given a string, returns a zeromq localhost tcp address (ex:
 * tcp://127.15.21.22:11111).  
 *
 * On windows we don't get zeromq IPC sockets. Hence, the easiest thing to do
 * is to remap ipc sockets to tcp addresses.
 *
 * When the server is started with address=default mode, on *nix systems we
 * map to ipc://something or order. Instead, on windows systems
 * we must map to tcp://[arbitrary local IP] where there is optimally, 
 * a 1-1 correspondence between the local IP and the PID.
 * 
 * So, here are the rules:
 * - We cannot generate any port number <= 1024
 * - Lets about 127.0.0.1 because too many stuff like to live there
 * - 127.0.0.0 is invalid. (network address) 
 * - 127.255.255.255 is invalid (broadcast address)
 */
std::string hash_string_to_tcp_address(const std::string& s) {
  std::string md5sum = graphlab::md5_raw(s);
  // we get approximately 5 bytes of entropy (yes really somewhat less) 

  unsigned char addr[4];
  addr[0] = 127;
  addr[1] = md5sum[0];
  addr[2] = md5sum[1];
  addr[3] = md5sum[2];
  uint16_t port = (uint16_t)(md5sum[3]) * 256 + md5sum[4];

  // validate
  if ((addr[1] == 0 && addr[2] == 0 && addr[3] == 0) ||  // network address
      (addr[1] == 0 && addr[2] == 0 && addr[3] == 1) ||  // common address
      (addr[1] == 255 && addr[2] == 255 && addr[3] == 255) ||  // broadcast
      (port <= 1024)) { // bad port
    // bad. this is network name
    // rehash
    return hash_string_to_tcp_address(md5sum);
  }

  // ok generate the string
  std::stringstream strm; 
  strm << "tcp://" << (int)(addr[0]) << "."
                   << (int)(addr[1]) << "."
                   << (int)(addr[2]) << "."
                   << (int)(addr[3]) << ":"
                   << (int)(port);

  std::string s_out = strm.str();

  logstream(LOG_INFO) << "normalize_address: Hashed ipc address '" << s << "' to '"
                      << s_out << "'." << std::endl;
  return s_out;
}
Example #2
0
std::string normalize_address(const std::string& address) {
#ifdef _WIN32
  if (boost::starts_with(address, "ipc://")) {
    return hash_string_to_tcp_address(address);
  } else {
    return address;
  }
#else
  /*
   *
  ipc sockets on Linux and Mac use Unix domain sockets which have a maximum
  length defined by

  #include <iostream>
  #include <sys/socket.h>
  #include <sys/un.h>

  int main() {
    struct sockaddr_un my_addr;
    std::cout << sizeof(my_addr.sun_path) << std::endl;
  }
  This appears to be 104 on Mac OS X 10.11 and 108 on a Ubuntu machine
  (length includes the null terminator).

  See http://man7.org/linux/man-pages/man7/unix.7.html
  */
  struct sockaddr_un un_addr;
  size_t max_length = sizeof(un_addr.sun_path) - 1;  // null terminator
  if (boost::starts_with(address, "ipc://") &&
      address.length() > max_length) { // strictly this leaves a 5 char buffer
                                       // since we didn't strip the ipc://
     // we hash it to a file we put in /tmp
     // we could use $TMPDIR but that might be a bad idea.
     // since $TMPDIR could bump the length much bigger again.
     // with /tmp the length is bounded to strlen("/tmp") + md5 length.
    std::string md5_hash = graphlab::md5(address);
    return "ipc:///tmp/" + md5_hash;
  } else {
    return address;
  }
#endif
}
Example #3
0
std::string normalize_address(const std::string& address) {

  bool use_tcp_fallback = (FORCE_IPC_TO_TCP_FALLBACK != 0);

  std::string address_out;

#ifdef _WIN32
  use_tcp_fallback = true;
#endif

  if(use_tcp_fallback) {

    logstream(LOG_INFO) << "normalize_address: Using TCP fallback mode." << std::endl;
    
    if (boost::starts_with(address, "ipc://")) {
      address_out = hash_string_to_tcp_address(address);
    } else {
      address_out = address;
    }
  } else {
    /*
     *
     ipc sockets on Linux and Mac use Unix domain sockets which have a maximum
     length defined by

     #include <iostream>
     #include <sys/socket.h>
     #include <sys/un.h>

     int main() {
     struct sockaddr_un my_addr;
     std::cout << sizeof(my_addr.sun_path) << std::endl;
     }
     This appears to be 104 on Mac OS X 10.11 and 108 on a Ubuntu machine
     (length includes the null terminator).

     See http://man7.org/linux/man-pages/man7/unix.7.html
    */
    struct sockaddr_un un_addr;
    size_t max_length = sizeof(un_addr.sun_path) - 1;  // null terminator
    if (boost::starts_with(address, "ipc://") &&
        address.length() > max_length) { // strictly this leaves a 5 char buffer
      // since we didn't strip the ipc://
      // we hash it to a file we put in /tmp
      // we could use $TMPDIR but that might be a bad idea.
      // since $TMPDIR could bump the length much bigger again.
      // with /tmp the length is bounded to strlen("/tmp") + md5 length.
      std::string md5_hash = graphlab::md5(address);
      address_out = "ipc:///tmp/" + md5_hash;
    } else {
      address_out = address;
    }
  }

  if(address_out == address) {
    logstream(LOG_INFO) << "normalize_address: kept '" << address_out << "'." << std::endl;
  } else {
    logstream(LOG_INFO) << "normalize_address: '" << address << "' --> '"
                        << address_out << "'." << std::endl;
  }

  return address_out;
}