OLD | NEW |
---|---|
(Empty) | |
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 "remoting/test/fake_network_dispatcher.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/location.h" | |
9 #include "base/single_thread_task_runner.h" | |
10 #include "net/base/io_buffer.h" | |
11 | |
12 #include <arpa/inet.h> | |
13 | |
14 namespace remoting { | |
15 | |
16 FakeNetworkDispatcher::FakeNetworkDispatcher() | |
17 : allocated_address_(0) { | |
18 } | |
19 | |
20 FakeNetworkDispatcher::~FakeNetworkDispatcher() { | |
21 CHECK(nodes_.empty()); | |
22 } | |
23 | |
24 talk_base::IPAddress FakeNetworkDispatcher::AllocateAddress() { | |
25 in6_addr addr; | |
26 memset(&addr, 0, sizeof(addr)); | |
27 | |
28 // fc00::/7 is reserved for unique local addresses. | |
29 addr.s6_addr[0] = 0xfc; | |
30 | |
31 // Copy |allocated_address_| to the end of |addr|. | |
32 ++allocated_address_; | |
33 for (size_t i = 0; i < sizeof(allocated_address_); ++i) { | |
34 addr.s6_addr[15 - i] = (allocated_address_ >> (8 * i)) & 0xff; | |
35 } | |
36 | |
37 return talk_base::IPAddress(addr); | |
38 } | |
39 | |
40 void FakeNetworkDispatcher::AddNode(Node* node) { | |
41 DCHECK(node->GetThread()->BelongsToCurrentThread()); | |
42 | |
43 base::AutoLock auto_lock(nodes_lock_); | |
44 DCHECK(nodes_.find(node->GetAddress()) == nodes_.end()); | |
45 nodes_[node->GetAddress()] = node; | |
46 } | |
47 | |
48 void FakeNetworkDispatcher::RemoveNode(Node* node) { | |
49 DCHECK(node->GetThread()->BelongsToCurrentThread()); | |
50 | |
51 base::AutoLock auto_lock(nodes_lock_); | |
52 DCHECK(nodes_[node->GetAddress()] == node); | |
53 nodes_.erase(node->GetAddress()); | |
54 } | |
55 | |
56 void FakeNetworkDispatcher::DeliverPacket( | |
57 const talk_base::SocketAddress& from, | |
58 const talk_base::SocketAddress& to, | |
59 const scoped_refptr<net::IOBuffer>& data, | |
60 int data_size) { | |
61 Node* node; | |
62 { | |
63 base::AutoLock auto_lock(nodes_lock_); | |
64 | |
65 NodesMap::iterator node_it = nodes_.find(to.ipaddr()); | |
66 if (node_it == nodes_.end()) { | |
67 LOG(ERROR) << "Tried to deliver packet to unknown target: " | |
68 << to.ToString(); | |
69 return; | |
70 } | |
71 | |
72 node = node_it->second; | |
73 | |
74 // Check if |node| belongs to a different thread and post a task in that | |
75 // case. | |
76 scoped_refptr<base::SingleThreadTaskRunner> task_runner = node->GetThread(); | |
77 if (!task_runner->BelongsToCurrentThread()) { | |
78 task_runner->PostTask(FROM_HERE, | |
79 base::Bind(&FakeNetworkDispatcher::DeliverPacket, | |
80 this, from, to, data, data_size)); | |
81 return; | |
82 } | |
83 } | |
84 | |
85 // Call ReceivePacket() without lock held. It's safe because at this point we | |
86 // know that |node| belongs to the current thread. | |
87 node->ReceivePacket(from, to, data, data_size); | |
88 } | |
89 | |
rmsousa
2014/08/12 20:42:10
nit: extra line break
Sergey Ulanov
2014/08/16 00:03:34
Done.
| |
90 | |
91 } // namespace remoting | |
OLD | NEW |