X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FIPAddressV6.h;h=d4876af6c6fb70c37c942d35dec31b5ac5a4315b;hb=a5a5daef1f43d6222a0261e856edd3a62f2c7b24;hp=134d6de9c146392f2ef760dfa794dd30c17aa3a4;hpb=dced19f55cf70ce7c0b881af5125d95b76321373;p=folly.git diff --git a/folly/IPAddressV6.h b/folly/IPAddressV6.h index 134d6de9..d4876af6 100644 --- a/folly/IPAddressV6.h +++ b/folly/IPAddressV6.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 Facebook, Inc. + * Copyright 2015 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,9 +23,9 @@ #include -#include "folly/Hash.h" -#include "folly/Range.h" -#include "folly/detail/IPAddress.h" +#include +#include +#include namespace folly { @@ -51,6 +51,17 @@ typedef std::array ByteArray16; * isTeredo, isIPv4Mapped, tryCreateIPv4, type * * @see IPAddress + * + * Notes on scope ID parsing: + * + * getaddrinfo() uses if_nametoindex() to convert interface names + * into a numerical index. For instance, + * "fe80::202:c9ff:fec1:ee08%eth0" may return scope ID 2 on some + * hosts, but other numbers on other hosts. It will fail entirely on + * hosts without an eth0 interface. + * + * Serializing / Deserializing IPAddressB6's on different hosts + * that use link-local scoping probably won't work. */ class IPAddressV6 : boost::totally_ordered { public: @@ -71,6 +82,10 @@ class IPAddressV6 : boost::totally_ordered { // Binary prefix for 6to4 networks static const uint32_t PREFIX_6TO4; + // Size of std::string returned by toFullyQualified. + static constexpr size_t kToFullyQualifiedSize = + 8 /*words*/ * 4 /*hex chars per word*/ + 7 /*separators*/; + /** * Create a new IPAddress instance from the provided binary data. * @throws IPAddressFormatException if the input length is not 16 bytes. @@ -90,6 +105,7 @@ class IPAddressV6 : boost::totally_ordered { // Create an IPAddressV6 from a string // @throws IPAddressFormatException + // explicit IPAddressV6(StringPiece ip); // ByteArray16 constructor @@ -98,6 +114,9 @@ class IPAddressV6 : boost::totally_ordered { // in6_addr constructor explicit IPAddressV6(const in6_addr& src); + // sockaddr_in6 constructor + explicit IPAddressV6(const sockaddr_in6& src); + /** * Create a link-local IPAddressV6 from the specified ethernet MAC address. */ @@ -209,10 +228,16 @@ class IPAddressV6 : boost::totally_ordered { // return underlying in6_addr structure in6_addr toAddr() const { return addr_.in6Addr_; } + uint16_t getScopeId() const { return scope_; } + void setScopeId(uint16_t scope) { + scope_ = scope; + } + sockaddr_in6 toSockAddr() const { sockaddr_in6 addr; memset(&addr, 0, sizeof(sockaddr_in6)); addr.sin6_family = AF_INET6; + addr.sin6_scope_id = scope_; memcpy(&addr.sin6_addr, &addr_.in6Addr_, sizeof(in6_addr)); return addr; } @@ -294,6 +319,10 @@ class IPAddressV6 : boost::totally_ordered { explicit AddressStorage(MacAddress mac); } addr_; + // Link-local scope id. This should always be 0 for IPAddresses that + // are *not* link-local. + uint16_t scope_{0}; + static const std::array masks_; /** @@ -315,11 +344,18 @@ void toAppend(IPAddressV6 addr, fbstring* result); * Return true if two addresses are equal. */ inline bool operator==(const IPAddressV6& addr1, const IPAddressV6& addr2) { - return (std::memcmp(addr1.toAddr().s6_addr, addr2.toAddr().s6_addr, 16) == 0); + return (std::memcmp(addr1.toAddr().s6_addr, addr2.toAddr().s6_addr, 16) == 0) + && addr1.getScopeId() == addr2.getScopeId(); } // Return true if addr1 < addr2 inline bool operator<(const IPAddressV6& addr1, const IPAddressV6& addr2) { - return (std::memcmp(addr1.toAddr().s6_addr, addr2.toAddr().s6_addr, 16) < 0); + auto cmp = std::memcmp(addr1.toAddr().s6_addr, + addr2.toAddr().s6_addr, 16) < 0; + if (!cmp) { + return addr1.getScopeId() < addr2.getScopeId(); + } else { + return cmp; + } } } // folly