1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <algorithm>
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/net_errors.h"
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/dns/mock_mdns_socket_factory.h"
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing testing::_;
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing testing::Invoke;
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace net {
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MockMDnsDatagramServerSocket::MockMDnsDatagramServerSocket(
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    AddressFamily address_family) {
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  local_address_ = GetMDnsIPEndPoint(address_family);
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMockMDnsDatagramServerSocket::~MockMDnsDatagramServerSocket() {
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint MockMDnsDatagramServerSocket::SendTo(IOBuffer* buf, int buf_len,
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                         const IPEndPoint& address,
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                         const CompletionCallback& callback) {
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return SendToInternal(std::string(buf->data(), buf_len), address.ToString(),
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        callback);
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int MockMDnsDatagramServerSocket::GetLocalAddress(IPEndPoint* address) const {
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  *address = local_address_;
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return OK;
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MockMDnsDatagramServerSocket::SetResponsePacket(
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string response_packet) {
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  response_packet_ = response_packet;
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint MockMDnsDatagramServerSocket::HandleRecvNow(
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    IOBuffer* buffer, int size, IPEndPoint* address,
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const CompletionCallback& callback) {
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int size_returned =
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      std::min(response_packet_.size(), static_cast<size_t>(size));
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  memcpy(buffer->data(), response_packet_.data(), size_returned);
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return size_returned;
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint MockMDnsDatagramServerSocket::HandleRecvLater(
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    IOBuffer* buffer, int size, IPEndPoint* address,
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const CompletionCallback& callback) {
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = HandleRecvNow(buffer, size, address, callback);
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, rv));
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return ERR_IO_PENDING;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMockMDnsSocketFactory::MockMDnsSocketFactory() {
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMockMDnsSocketFactory::~MockMDnsSocketFactory() {
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MockMDnsSocketFactory::CreateSockets(
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<DatagramServerSocket>* sockets) {
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateSocket(ADDRESS_FAMILY_IPV4, sockets);
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateSocket(ADDRESS_FAMILY_IPV6, sockets);
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MockMDnsSocketFactory::CreateSocket(
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    AddressFamily address_family,
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<DatagramServerSocket>* sockets) {
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<testing::NiceMock<MockMDnsDatagramServerSocket> > new_socket(
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new testing::NiceMock<MockMDnsDatagramServerSocket>(address_family));
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ON_CALL(*new_socket, SendToInternal(_, _, _))
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillByDefault(Invoke(
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          this,
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &MockMDnsSocketFactory::SendToInternal));
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ON_CALL(*new_socket, RecvFrom(_, _, _, _))
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillByDefault(Invoke(
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          this,
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          &MockMDnsSocketFactory::RecvFromInternal));
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sockets->push_back(new_socket.release());
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void MockMDnsSocketFactory::SimulateReceive(const uint8* packet, int size) {
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(recv_buffer_size_ >= size);
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(recv_buffer_.get());
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!recv_callback_.is_null());
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  memcpy(recv_buffer_->data(), packet, size);
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CompletionCallback recv_callback = recv_callback_;
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  recv_callback_.Reset();
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  recv_callback.Run(size);
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint MockMDnsSocketFactory::RecvFromInternal(
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    IOBuffer* buffer, int size,
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    IPEndPoint* address,
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const CompletionCallback& callback) {
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    recv_buffer_ = buffer;
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    recv_buffer_size_ = size;
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    recv_callback_ = callback;
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return ERR_IO_PENDING;
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint MockMDnsSocketFactory::SendToInternal(
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& packet, const std::string& address,
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const CompletionCallback& callback) {
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnSendTo(packet);
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return packet.size();
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace net
117