OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #ifndef WEBRTC_P2P_STUNPROBER_STUNPROBER_DEPENDENCIES_H_ | |
12 #define WEBRTC_P2P_STUNPROBER_STUNPROBER_DEPENDENCIES_H_ | |
13 | |
14 #include "webrtc/base/checks.h" | |
15 #include "webrtc/base/helpers.h" | |
16 #include "webrtc/base/logging.h" | |
17 #include "webrtc/base/scoped_ptr.h" | |
18 #include "webrtc/base/thread.h" | |
19 #include "webrtc/base/timeutils.h" | |
20 #include "webrtc/p2p/stunprober/stunprober.h" | |
21 | |
22 // Common classes used by both the command line driver and the unit tests. | |
23 namespace stunprober { | |
24 | |
25 class Socket : public ClientSocketInterface, | |
26 public ServerSocketInterface, | |
27 public sigslot::has_slots<> { | |
28 public: | |
29 explicit Socket(rtc::AsyncSocket* socket) : socket_(socket) { | |
30 socket_->SignalReadEvent.connect(this, &Socket::OnReadEvent); | |
31 socket_->SignalWriteEvent.connect(this, &Socket::OnWriteEvent); | |
32 } | |
33 | |
34 int Connect(const rtc::SocketAddress& addr) override { | |
35 return MapResult(socket_->Connect(addr)); | |
36 } | |
37 | |
38 int SendTo(const rtc::SocketAddress& addr, | |
39 char* buf, | |
40 size_t buf_len, | |
41 AsyncCallback callback) override { | |
42 write_ = NetworkWrite(addr, buf, buf_len, callback); | |
43 return MapResult(socket_->SendTo(buf, buf_len, addr)); | |
44 } | |
45 | |
46 int RecvFrom(char* buf, | |
47 size_t buf_len, | |
48 rtc::SocketAddress* addr, | |
49 AsyncCallback callback) override { | |
50 read_ = NetworkRead(buf, buf_len, addr, callback); | |
51 return MapResult(socket_->RecvFrom(buf, buf_len, addr)); | |
52 } | |
53 | |
54 int GetLocalAddress(rtc::SocketAddress* local_address) override { | |
55 *local_address = socket_->GetLocalAddress(); | |
56 return 0; | |
57 } | |
58 | |
59 void Close() override { socket_->Close(); } | |
60 | |
61 virtual ~Socket() {} | |
62 | |
63 protected: | |
64 int MapResult(int rv) { | |
65 if (rv >= 0) { | |
66 return rv; | |
67 } | |
68 int err = socket_->GetError(); | |
69 if (err == EWOULDBLOCK || err == EAGAIN) { | |
70 return IO_PENDING; | |
71 } else { | |
72 return FAILED; | |
73 } | |
74 } | |
75 | |
76 void OnReadEvent(rtc::AsyncSocket* socket) { | |
77 DCHECK(socket_ == socket); | |
78 NetworkRead read = read_; | |
79 read_ = NetworkRead(); | |
80 if (!read.callback.empty()) { | |
81 read.callback(socket_->RecvFrom(read.buf, read.buf_len, read.addr)); | |
82 } | |
83 } | |
84 | |
85 void OnWriteEvent(rtc::AsyncSocket* socket) { | |
86 DCHECK(socket_ == socket); | |
87 NetworkWrite write = write_; | |
88 write_ = NetworkWrite(); | |
89 if (!write.callback.empty()) { | |
90 write.callback(socket_->SendTo(write.buf, write.buf_len, write.addr)); | |
91 } | |
92 } | |
93 | |
94 struct NetworkWrite { | |
95 NetworkWrite() : buf(nullptr), buf_len(0) {} | |
96 NetworkWrite(const rtc::SocketAddress& addr, | |
97 char* buf, | |
98 size_t buf_len, | |
99 AsyncCallback callback) | |
100 : buf(buf), buf_len(buf_len), addr(addr), callback(callback) {} | |
101 char* buf; | |
102 size_t buf_len; | |
103 rtc::SocketAddress addr; | |
104 AsyncCallback callback; | |
105 }; | |
106 | |
107 NetworkWrite write_; | |
108 | |
109 struct NetworkRead { | |
110 NetworkRead() : buf(nullptr), buf_len(0) {} | |
111 NetworkRead(char* buf, | |
112 size_t buf_len, | |
113 rtc::SocketAddress* addr, | |
114 AsyncCallback callback) | |
115 : buf(buf), buf_len(buf_len), addr(addr), callback(callback) {} | |
116 | |
117 char* buf; | |
118 size_t buf_len; | |
119 rtc::SocketAddress* addr; | |
120 AsyncCallback callback; | |
121 }; | |
122 | |
123 NetworkRead read_; | |
124 | |
125 rtc::scoped_ptr<rtc::AsyncSocket> socket_; | |
126 }; | |
127 | |
128 class SocketFactory : public SocketFactoryInterface { | |
129 public: | |
130 ClientSocketInterface* CreateClientSocket() override { | |
131 return new Socket( | |
132 rtc::Thread::Current()->socketserver()->CreateAsyncSocket(SOCK_DGRAM)); | |
133 } | |
134 ServerSocketInterface* CreateServerSocket(size_t send_buffer_size, | |
135 size_t recv_buffer_size) override { | |
136 rtc::scoped_ptr<rtc::AsyncSocket> socket( | |
137 rtc::Thread::Current()->socketserver()->CreateAsyncSocket(SOCK_DGRAM)); | |
138 | |
139 if (socket) { | |
140 socket->SetOption(rtc::AsyncSocket::OPT_SNDBUF, | |
141 static_cast<int>(send_buffer_size)); | |
142 socket->SetOption(rtc::AsyncSocket::OPT_RCVBUF, | |
143 static_cast<int>(recv_buffer_size)); | |
144 return new Socket(socket.release()); | |
145 } else { | |
146 return nullptr; | |
147 } | |
148 } | |
149 }; | |
150 | |
151 class TaskRunner : public TaskRunnerInterface, public rtc::MessageHandler { | |
152 protected: | |
153 class CallbackMessageData : public rtc::MessageData { | |
154 public: | |
155 explicit CallbackMessageData(rtc::Callback0<void> callback) | |
156 : callback_(callback) {} | |
157 rtc::Callback0<void> callback_; | |
158 }; | |
159 | |
160 public: | |
161 void PostTask(rtc::Callback0<void> callback, uint32_t delay_ms) { | |
162 if (delay_ms == 0) { | |
163 rtc::Thread::Current()->Post(this, 0, new CallbackMessageData(callback)); | |
164 } else { | |
165 rtc::Thread::Current()->PostDelayed(delay_ms, this, 0, | |
166 new CallbackMessageData(callback)); | |
167 } | |
168 } | |
169 | |
170 void OnMessage(rtc::Message* msg) { | |
171 rtc::scoped_ptr<CallbackMessageData> callback( | |
172 reinterpret_cast<CallbackMessageData*>(msg->pdata)); | |
173 callback->callback_(); | |
174 } | |
175 }; | |
176 | |
177 } // namespace stunprober | |
178 #endif // WEBRTC_P2P_STUNPROBER_STUNPROBER_DEPENDENCIES_H_ | |
OLD | NEW |