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/third_party/quiche/src/quic/core/quic_socket_address_coder.h"
6 
7 #include <cstring>
8 #include <string>
9 #include <vector>
10 
11 namespace quic {
12 
13 namespace {
14 
15 // For convenience, the values of these constants match the values of AF_INET
16 // and AF_INET6 on Linux.
17 const uint16_t kIPv4 = 2;
18 const uint16_t kIPv6 = 10;
19 
20 }  // namespace
21 
QuicSocketAddressCoder()22 QuicSocketAddressCoder::QuicSocketAddressCoder() {}
23 
QuicSocketAddressCoder(const QuicSocketAddress & address)24 QuicSocketAddressCoder::QuicSocketAddressCoder(const QuicSocketAddress& address)
25     : address_(address) {}
26 
~QuicSocketAddressCoder()27 QuicSocketAddressCoder::~QuicSocketAddressCoder() {}
28 
Encode() const29 std::string QuicSocketAddressCoder::Encode() const {
30   std::string serialized;
31   uint16_t address_family;
32   switch (address_.host().address_family()) {
33     case IpAddressFamily::IP_V4:
34       address_family = kIPv4;
35       break;
36     case IpAddressFamily::IP_V6:
37       address_family = kIPv6;
38       break;
39     default:
40       return serialized;
41   }
42   serialized.append(reinterpret_cast<const char*>(&address_family),
43                     sizeof(address_family));
44   serialized.append(address_.host().ToPackedString());
45   uint16_t port = address_.port();
46   serialized.append(reinterpret_cast<const char*>(&port), sizeof(port));
47   return serialized;
48 }
49 
Decode(const char * data,size_t length)50 bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
51   uint16_t address_family;
52   if (length < sizeof(address_family)) {
53     return false;
54   }
55   memcpy(&address_family, data, sizeof(address_family));
56   data += sizeof(address_family);
57   length -= sizeof(address_family);
58 
59   size_t ip_length;
60   switch (address_family) {
61     case kIPv4:
62       ip_length = QuicIpAddress::kIPv4AddressSize;
63       break;
64     case kIPv6:
65       ip_length = QuicIpAddress::kIPv6AddressSize;
66       break;
67     default:
68       return false;
69   }
70   if (length < ip_length) {
71     return false;
72   }
73   std::vector<uint8_t> ip(ip_length);
74   memcpy(&ip[0], data, ip_length);
75   data += ip_length;
76   length -= ip_length;
77 
78   uint16_t port;
79   if (length != sizeof(port)) {
80     return false;
81   }
82   memcpy(&port, data, length);
83 
84   QuicIpAddress ip_address;
85   ip_address.FromPackedString(reinterpret_cast<const char*>(&ip[0]), ip_length);
86   address_ = QuicSocketAddress(ip_address, port);
87   return true;
88 }
89 
90 }  // namespace quic
91