blob: 5eeb95d3bcbb1eac4ee20d0554b65fce40eb7628 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/core/quic_socket_address_coder.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
danzh9424add2019-06-06 14:04:36 -07007#include <cstring>
8#include <string>
9#include <vector>
10
QUICHE teama6ef0a62019-03-07 20:34:33 -050011namespace quic {
12
13namespace {
14
15// For convenience, the values of these constants match the values of AF_INET
16// and AF_INET6 on Linux.
17const uint16_t kIPv4 = 2;
18const uint16_t kIPv6 = 10;
19
20} // namespace
21
22QuicSocketAddressCoder::QuicSocketAddressCoder() {}
23
24QuicSocketAddressCoder::QuicSocketAddressCoder(const QuicSocketAddress& address)
25 : address_(address) {}
26
27QuicSocketAddressCoder::~QuicSocketAddressCoder() {}
28
vasilvvc48c8712019-03-11 13:38:16 -070029std::string QuicSocketAddressCoder::Encode() const {
30 std::string serialized;
QUICHE teama6ef0a62019-03-07 20:34:33 -050031 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
50bool 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