[ 
https://issues.apache.org/jira/browse/MESOS-1919?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14184331#comment-14184331
 ] 

Michael Park commented on MESOS-1919:
-------------------------------------

I agree with [~jvanremoortere] that we should avoid the use of {{std::vector}} 
and I'm in favor of the {{union}} approach. It looks to me like you're trying 
to piece together an abstraction for IP address (based on the use of 
{{in_addr}}) but I think it would make more sense to use {{sockaddr_in}} to 
present a *node* instead, which encapsulates an IP address + port number. This 
way we can leverage all of the functions that take {{sockaddr *}}.

Here's a sample implementation of it using the {{union}} approach. Implicit 
conversion to {{sockaddr *}} is allowed for natural use with functions that 
take {{sockaddr *}}, but of course we could make it explicit if we prefer. The 
functions {{getAddress}} and {{getPort}} are shown for example purposes.

{code:title=node.h|borderStyle=solid}
class Node {
public:
  explicit Node(uint16_t family, uint16_t port, const char *address) : 
storage() {
    storage.ss_family = family;
    int result;
    switch (storage.ss_family) {
      case AF_INET: {
        ipv4.sin_port = htons(port);
        result = inet_pton(storage.ss_family, address, &ipv4.sin_addr);
        break;
      }  // case
      case AF_INET6: {
        ipv6.sin6_port = htons(port);
        result = inet_pton(storage.ss_family, address, &ipv6.sin6_addr);
        break;
      }  // case
    }  // switch
    if (result < 0) {
      // Error: system
    } else if (result == 0) {
      // Error: parse
    }
  }

  // ...

  operator const sockaddr *() const { return &generic; }
  operator sockaddr *() { return &generic; }

  std::string getAddress() const {
    std::string result;
    switch (storage.ss_family) {
      case AF_INET: {
        char buffer[INET_ADDRSTRLEN];
        if (inet_ntop(storage.ss_family, &ipv4.sin_addr, buffer, 
sizeof(buffer)) == NULL) {
          // Error
        }
        result = buffer;
        break;
      }
      case AF_INET6: {
        char buffer[INET6_ADDRSTRLEN];
        if (inet_ntop(storage.ss_family, &ipv6.sin6_addr, buffer, 
sizeof(buffer)) == NULL) {
          // Error
        }
        result = buffer;
        break;
      }
    }
    return result;
  }

  uint16_t getPort() const {
    uint16_t result;
    switch (storage.ss_family) {
      case AF_INET: {
        result = ipv4.sin_port;
        break;
      }
      case AF_INET6: {
        result = ipv6.sin6_port;
        break;
      }
    }
    return ntohs(result);
  }

private:
  union {
    sockaddr_storage storage;
    sockaddr_in ipv4;
    sockaddr_in6 ipv6;
    sockaddr generic;
  };
};
{code}

> Create IP address abstraction
> -----------------------------
>
>                 Key: MESOS-1919
>                 URL: https://issues.apache.org/jira/browse/MESOS-1919
>             Project: Mesos
>          Issue Type: Task
>          Components: libprocess
>            Reporter: Dominic Hamon
>            Assignee: Evelina Dumitrescu
>            Priority: Minor
>
> in the code many functions need only the ip address to be passed as a 
> parameter. I don't think it would be desirable to use a struct 
> SockaddrStorage (MESOS-1916).
> Consider using a {{std::vector<unsigned char>}} (see {{typedef 
> std::vector<unsigned char> IPAddressNumber;}} in the Chromium project)



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to