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
7using std::string;
8
9namespace net {
10
11namespace {
12
13// For convenience, the values of these constants match the values of AF_INET
14// and AF_INET6 on Linux.
15const uint16 kIPv4 = 2;
16const uint16 kIPv6 = 10;
17
18}  // namespace
19
20QuicSocketAddressCoder::QuicSocketAddressCoder() {
21}
22
23QuicSocketAddressCoder::QuicSocketAddressCoder(const IPEndPoint& address)
24    : address_(address) {
25}
26
27QuicSocketAddressCoder::~QuicSocketAddressCoder() {
28}
29
30string 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
51bool 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