Home | History | Annotate | Download | only in quic
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/quic_socket_address_coder.h"
      6 
      7 using std::string;
      8 
      9 namespace net {
     10 
     11 namespace {
     12 
     13 // For convenience, the values of these constants match the values of AF_INET
     14 // and AF_INET6 on Linux.
     15 const uint16 kIPv4 = 2;
     16 const uint16 kIPv6 = 10;
     17 
     18 }  // namespace
     19 
     20 QuicSocketAddressCoder::QuicSocketAddressCoder() {
     21 }
     22 
     23 QuicSocketAddressCoder::QuicSocketAddressCoder(const IPEndPoint& address)
     24     : address_(address) {
     25 }
     26 
     27 QuicSocketAddressCoder::~QuicSocketAddressCoder() {
     28 }
     29 
     30 string QuicSocketAddressCoder::Encode() const {
     31   string serialized;
     32   uint16 address_family;
     33   switch (address_.GetSockAddrFamily()) {
     34     case AF_INET:
     35       address_family = kIPv4;
     36       break;
     37     case AF_INET6:
     38       address_family = kIPv6;
     39       break;
     40     default:
     41       return serialized;
     42   }
     43   serialized.append(reinterpret_cast<const char*>(&address_family),
     44                     sizeof(address_family));
     45   serialized.append(IPAddressToPackedString(address_.address()));
     46   uint16 port = address_.port();
     47   serialized.append(reinterpret_cast<const char*>(&port), sizeof(port));
     48   return serialized;
     49 }
     50 
     51 bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
     52   uint16 address_family;
     53   if (length < sizeof(address_family)) {
     54     return false;
     55   }
     56   memcpy(&address_family, data, sizeof(address_family));
     57   data += sizeof(address_family);
     58   length -= sizeof(address_family);
     59 
     60   size_t ip_length;
     61   switch (address_family) {
     62     case kIPv4:
     63       ip_length = kIPv4AddressSize;
     64       break;
     65     case kIPv6:
     66       ip_length = kIPv6AddressSize;
     67       break;
     68     default:
     69       return false;
     70   }
     71   if (length < ip_length) {
     72     return false;
     73   }
     74   IPAddressNumber ip(ip_length);
     75   memcpy(&ip[0], data, ip_length);
     76   data += ip_length;
     77   length -= ip_length;
     78 
     79   uint16 port;
     80   if (length != sizeof(port)) {
     81     return false;
     82   }
     83   memcpy(&port, data, length);
     84 
     85   address_ = IPEndPoint(ip, port);
     86   return true;
     87 }
     88 
     89 }  // namespace net
     90