15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_socket_address_coder.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using std::string;
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// For convenience, the values of these constants match the values of AF_INET
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and AF_INET6 on Linux.
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint16 kIPv4 = 2;
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint16 kIPv6 = 10;
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicSocketAddressCoder::QuicSocketAddressCoder() {
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicSocketAddressCoder::QuicSocketAddressCoder(const IPEndPoint& address)
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : address_(address) {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicSocketAddressCoder::~QuicSocketAddressCoder() {
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)string QuicSocketAddressCoder::Encode() const {
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  string serialized;
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint16 address_family;
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (address_.GetSockAddrFamily()) {
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case AF_INET:
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      address_family = kIPv4;
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case AF_INET6:
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      address_family = kIPv6;
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return serialized;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  serialized.append(reinterpret_cast<const char*>(&address_family),
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    sizeof(address_family));
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  serialized.append(IPAddressToPackedString(address_.address()));
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint16 port = address_.port();
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  serialized.append(reinterpret_cast<const char*>(&port), sizeof(port));
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return serialized;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicSocketAddressCoder::Decode(const char* data, size_t length) {
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint16 address_family;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (length < sizeof(address_family)) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memcpy(&address_family, data, sizeof(address_family));
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data += sizeof(address_family);
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  length -= sizeof(address_family);
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t ip_length;
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (address_family) {
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case kIPv4:
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ip_length = kIPv4AddressSize;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case kIPv6:
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ip_length = kIPv6AddressSize;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (length < ip_length) {
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  IPAddressNumber ip(ip_length);
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memcpy(&ip[0], data, ip_length);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data += ip_length;
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  length -= ip_length;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint16 port;
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (length != sizeof(port)) {
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memcpy(&port, data, length);
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  address_ = IPEndPoint(ip, port);
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
90