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