Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: net/websockets/websocket_throttle.cc

Issue 12033072: Include destination port for websocket throttling. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/websockets/websocket_throttle.h" 5 #include "net/websockets/websocket_throttle.h"
6 6
Takashi Toyoshima 2013/01/24 09:51:00 #include <algorithm>
Adam Rice 2013/01/25 04:07:36 Good catch. Done.
7 #include <set>
7 #include <string> 8 #include <string>
8 9
9 #include "base/hash_tables.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/singleton.h" 10 #include "base/memory/singleton.h"
12 #include "base/message_loop.h" 11 #include "base/message_loop.h"
13 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
14 #include "base/string_util.h" 13 #include "base/string_util.h"
15 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
16 #include "net/base/io_buffer.h" 15 #include "net/base/io_buffer.h"
17 #include "net/socket_stream/socket_stream.h" 16 #include "net/socket_stream/socket_stream.h"
18 #include "net/websockets/websocket_job.h" 17 #include "net/websockets/websocket_job.h"
19 18
20 namespace net { 19 namespace net {
21 20
22 static std::string IPEndPointToHashkey(const IPEndPoint& endpoint) {
23 return base::StringPrintf("%d:%s",
24 endpoint.GetFamily(),
25 base::HexEncode(&endpoint.address()[0],
26 endpoint.address().size()).c_str());
27 }
28
29 WebSocketThrottle::WebSocketThrottle() { 21 WebSocketThrottle::WebSocketThrottle() {
30 } 22 }
31 23
32 WebSocketThrottle::~WebSocketThrottle() { 24 WebSocketThrottle::~WebSocketThrottle() {
33 DCHECK(queue_.empty()); 25 DCHECK(queue_.empty());
34 DCHECK(addr_map_.empty()); 26 DCHECK(addr_map_.empty());
35 } 27 }
36 28
37 // static 29 // static
38 WebSocketThrottle* WebSocketThrottle::GetInstance() { 30 WebSocketThrottle* WebSocketThrottle::GetInstance() {
39 return Singleton<WebSocketThrottle>::get(); 31 return Singleton<WebSocketThrottle>::get();
40 } 32 }
41 33
42 void WebSocketThrottle::PutInQueue(WebSocketJob* job) { 34 void WebSocketThrottle::PutInQueue(WebSocketJob* job) {
43 queue_.push_back(job); 35 queue_.push_back(job);
44 const AddressList& address_list = job->address_list(); 36 const AddressList& address_list = job->address_list();
45 base::hash_set<std::string> address_set; 37 std::set<IPEndPoint> address_set;
46 for (AddressList::const_iterator addr_iter = address_list.begin(); 38 for (AddressList::const_iterator addr_iter = address_list.begin();
47 addr_iter != address_list.end(); 39 addr_iter != address_list.end();
48 ++addr_iter) { 40 ++addr_iter) {
49 std::string addrkey = IPEndPointToHashkey(*addr_iter); 41 const IPEndPoint& address = *addr_iter;
42 // If |address| is already processed, don't do it again.
43 if (!address_set.insert(address).second)
44 continue;
50 45
51 // If |addrkey| is already processed, don't do it again. 46 ConnectingAddressMap::iterator iter = addr_map_.find(address);
52 if (address_set.find(addrkey) != address_set.end())
53 continue;
54 address_set.insert(addrkey);
55
56 ConnectingAddressMap::iterator iter = addr_map_.find(addrkey);
57 if (iter == addr_map_.end()) { 47 if (iter == addr_map_.end()) {
58 ConnectingQueue* queue = new ConnectingQueue(); 48 ConnectingQueue* queue = new ConnectingQueue();
59 queue->push_back(job); 49 queue->push_back(job);
60 addr_map_[addrkey] = queue; 50 addr_map_[address] = queue;
61 } else { 51 } else {
62 iter->second->push_back(job); 52 iter->second->push_back(job);
63 job->SetWaiting(); 53 job->SetWaiting();
64 DVLOG(1) << "Waiting on " << addrkey; 54 DVLOG(1) << "Waiting on " << address.ToString();
65 } 55 }
66 } 56 }
67 } 57 }
68 58
69 void WebSocketThrottle::RemoveFromQueue(WebSocketJob* job) { 59 void WebSocketThrottle::RemoveFromQueue(WebSocketJob* job) {
70 bool in_queue = false; 60 ConnectingQueue::iterator queue_iter =
71 for (ConnectingQueue::iterator iter = queue_.begin(); 61 std::find(queue_.begin(), queue_.end(), job);
72 iter != queue_.end(); 62 if (queue_iter == queue_.end())
73 ++iter) {
74 if (*iter == job) {
75 queue_.erase(iter);
76 in_queue = true;
77 break;
78 }
79 }
80 if (!in_queue)
81 return; 63 return;
64 queue_.erase(queue_iter);
82 const AddressList& address_list = job->address_list(); 65 const AddressList& address_list = job->address_list();
83 base::hash_set<std::string> address_set; 66 std::set<IPEndPoint> address_set;
84 for (AddressList::const_iterator addr_iter = address_list.begin(); 67 for (AddressList::const_iterator addr_iter = address_list.begin();
85 addr_iter != address_list.end(); 68 addr_iter != address_list.end();
86 ++addr_iter) { 69 ++addr_iter) {
87 std::string addrkey = IPEndPointToHashkey(*addr_iter); 70 const IPEndPoint& address = *addr_iter;
88 // If |addrkey| is already processed, don't do it again. 71 // If |address| is already processed, don't do it again.
89 if (address_set.find(addrkey) != address_set.end()) 72 if (!address_set.insert(address).second)
90 continue; 73 continue;
91 address_set.insert(addrkey);
92 74
93 ConnectingAddressMap::iterator iter = addr_map_.find(addrkey); 75 ConnectingAddressMap::iterator map_iter = addr_map_.find(address);
94 DCHECK(iter != addr_map_.end()); 76 DCHECK(map_iter != addr_map_.end());
95 77
96 ConnectingQueue* queue = iter->second; 78 ConnectingQueue* queue = map_iter->second;
97 // Job may not be front of queue when job is closed early while waiting. 79 // Job may not be front of queue if the socket is closed while waiting.
98 for (ConnectingQueue::iterator iter = queue->begin(); 80 ConnectingQueue::iterator address_queue_iter =
99 iter != queue->end(); 81 std::find(queue->begin(), queue->end(), job);
100 ++iter) { 82 if (address_queue_iter != queue->end())
101 if (*iter == job) { 83 queue->erase(address_queue_iter);
102 queue->erase(iter);
103 break;
104 }
105 }
106 if (queue->empty()) { 84 if (queue->empty()) {
107 delete queue; 85 delete queue;
108 addr_map_.erase(iter); 86 addr_map_.erase(map_iter);
109 } 87 }
110 } 88 }
111 } 89 }
112 90
113 void WebSocketThrottle::WakeupSocketIfNecessary() { 91 void WebSocketThrottle::WakeupSocketIfNecessary() {
114 for (ConnectingQueue::iterator iter = queue_.begin(); 92 for (ConnectingQueue::iterator iter = queue_.begin();
115 iter != queue_.end(); 93 iter != queue_.end();
116 ++iter) { 94 ++iter) {
117 WebSocketJob* job = *iter; 95 WebSocketJob* job = *iter;
118 if (!job->IsWaiting()) 96 if (!job->IsWaiting())
119 continue; 97 continue;
120 98
121 bool should_wakeup = true; 99 bool should_wakeup = true;
122 const AddressList& address_list = job->address_list(); 100 const AddressList& address_list = job->address_list();
123 for (AddressList::const_iterator addr_iter = address_list.begin(); 101 for (AddressList::const_iterator addr_iter = address_list.begin();
124 addr_iter != address_list.end(); 102 addr_iter != address_list.end();
125 ++addr_iter) { 103 ++addr_iter) {
126 std::string addrkey = IPEndPointToHashkey(*addr_iter); 104 const IPEndPoint& address = *addr_iter;
127 ConnectingAddressMap::iterator iter = addr_map_.find(addrkey); 105 ConnectingAddressMap::iterator map_iter = addr_map_.find(address);
128 DCHECK(iter != addr_map_.end()); 106 DCHECK(map_iter != addr_map_.end());
129 ConnectingQueue* queue = iter->second; 107 ConnectingQueue* queue = map_iter->second;
130 if (job != queue->front()) { 108 if (job != queue->front()) {
131 should_wakeup = false; 109 should_wakeup = false;
132 break; 110 break;
133 } 111 }
134 } 112 }
135 if (should_wakeup) 113 if (should_wakeup)
136 job->Wakeup(); 114 job->Wakeup();
137 } 115 }
138 } 116 }
139 117
140 } // namespace net 118 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698