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

Marco Massenzio commented on MESOS-1201:
----------------------------------------

Ran into this while working on MESOS-2340 (related to MESOS-2298).

{{net::IP}} is internally consistent: you can create from a {{string}} and it 
stores it as an {{uint32}} (actually an {{in_addr}}) , then stream it back to a 
string and you’ll get back what you started with; for example, this works just 
fine:
{code}
TEST(IpTest, conversions)
{
  string ipStr = "192.169.10.11";
  std::ostringstream actual;

  net::IP ip = net::IP::parse(ipStr, AF_INET).get();
  actual << ip;
  ASSERT_EQ(ipStr, actual.str());
}
{code}

The problem is that the Protobuf “gets in the way:"  it stores the bytes in 
Network order - so, if you give them back to get a {{net::IP}} object it will 
cause weird stuff as the constructor expects them in “host order."

Here’s a (trivial) solution, which however is not a very robust fix:

{code}
  // you get the minfo from … magic!
  MasterInfo minfo = getMyMasterInfo(...);

  // then convert the bytes into host-order:
  net::IP ip{ ntohl(minfo.ip()) };
  // you can then generate back the original string ("192.168.1.10")
  std::ostringstream out;
  out << ip;
  return out.str();
{code}

Tthe long-term fix, however, would be to add a bool flag {{networkOrder}} to 
the {{net::IP(uint32 ip)}} constructor, I think (and maybe elaborate in the 
comment too); this is the current code:
{code}
  // Creates an IP from a 32 bit unsigned integer. Note that the
  // integer stores the IP address in host order.
  explicit IP(uint32_t _storage)
    : family_(AF_INET)
{code}
my suggestion would be to do something like:
{code}
  // Creates an IP from a 32 bit unsigned integer. Note that 'ip' is considered
  // to represent an IP address with the bytes in host order.
  //
  // They will be stored in network order internally; if they are already in
  // network order, pass in the 'networkOrder' flag as 'true'.
  explicit IP(uint32_t _storage, bool networkOrder = false)
    : family_(AF_INET)
{code}

BTW - right now, we can’t support INETv6; passing anything other than 
{{AF_INET}} will cause an error in this:
{code}
  static Try<IP> parse(const std::string& value, int family);
{code}

> Store IP addresses in host order
> --------------------------------
>
>                 Key: MESOS-1201
>                 URL: https://issues.apache.org/jira/browse/MESOS-1201
>             Project: Mesos
>          Issue Type: Bug
>          Components: technical debt
>            Reporter: Jie Yu
>
> Currently, in our code base, we store ip addresses in network order. For 
> instance, in UPID. Ironically, we store ports in host order.
> This can cause some subtle bugs which will be very hard to debug. For 
> example, we store ip in MasterInfo. Say the IP address is: 01.02.03.04. Since 
> we don't convert it into host order in our code, on x86 (little endian), it's 
> integer value will be 0x04030201. Now, we store it as an uint32 field in 
> MasterInfo protobuf. Protobuf will convert all integers into little endian 
> format, since x86 is little endian machine, no conversion will take place. As 
> a result, the value stored in probobuf will be 0x04030201. Now, if a big 
> endian machine reads this protobuf, it will do the conversion. If it later 
> interprets the ip from this integer, it will interpret it to be 04.03.02.01.
> So I plan to store all IP addresses in our code base to be in host order 
> (which is the common practice).
> We may have some compatibility issues as we store MasterInfo in ZooKeeper for 
> master detection and redirection. For example, what if the new code reads an 
> old MasterInfo? What would happen?



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

Reply via email to