OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2004 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 #include "webrtc/base/asyncudpsocket.h" | |
12 #include "webrtc/base/checks.h" | |
13 #include "webrtc/base/logging.h" | |
14 | |
15 namespace rtc { | |
16 | |
17 static const int BUF_SIZE = 64 * 1024; | |
18 | |
19 AsyncUDPSocket* AsyncUDPSocket::Create( | |
20 AsyncSocket* socket, | |
21 const SocketAddress& bind_address) { | |
22 std::unique_ptr<AsyncSocket> owned_socket(socket); | |
23 if (socket->Bind(bind_address) < 0) { | |
24 LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError(); | |
25 return nullptr; | |
26 } | |
27 return new AsyncUDPSocket(owned_socket.release()); | |
28 } | |
29 | |
30 AsyncUDPSocket* AsyncUDPSocket::Create(SocketFactory* factory, | |
31 const SocketAddress& bind_address) { | |
32 AsyncSocket* socket = | |
33 factory->CreateAsyncSocket(bind_address.family(), SOCK_DGRAM); | |
34 if (!socket) | |
35 return nullptr; | |
36 return Create(socket, bind_address); | |
37 } | |
38 | |
39 AsyncUDPSocket::AsyncUDPSocket(AsyncSocket* socket) | |
40 : socket_(socket) { | |
41 size_ = BUF_SIZE; | |
42 buf_ = new char[size_]; | |
43 | |
44 // The socket should start out readable but not writable. | |
45 socket_->SignalReadEvent.connect(this, &AsyncUDPSocket::OnReadEvent); | |
46 socket_->SignalWriteEvent.connect(this, &AsyncUDPSocket::OnWriteEvent); | |
47 } | |
48 | |
49 AsyncUDPSocket::~AsyncUDPSocket() { | |
50 delete [] buf_; | |
51 } | |
52 | |
53 SocketAddress AsyncUDPSocket::GetLocalAddress() const { | |
54 return socket_->GetLocalAddress(); | |
55 } | |
56 | |
57 SocketAddress AsyncUDPSocket::GetRemoteAddress() const { | |
58 return socket_->GetRemoteAddress(); | |
59 } | |
60 | |
61 int AsyncUDPSocket::Send(const void *pv, size_t cb, | |
62 const rtc::PacketOptions& options) { | |
63 rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis()); | |
64 int ret = socket_->Send(pv, cb); | |
65 SignalSentPacket(this, sent_packet); | |
66 return ret; | |
67 } | |
68 | |
69 int AsyncUDPSocket::SendTo(const void *pv, size_t cb, | |
70 const SocketAddress& addr, | |
71 const rtc::PacketOptions& options) { | |
72 rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis()); | |
73 int ret = socket_->SendTo(pv, cb, addr); | |
74 SignalSentPacket(this, sent_packet); | |
75 return ret; | |
76 } | |
77 | |
78 int AsyncUDPSocket::Close() { | |
79 return socket_->Close(); | |
80 } | |
81 | |
82 AsyncUDPSocket::State AsyncUDPSocket::GetState() const { | |
83 return STATE_BOUND; | |
84 } | |
85 | |
86 int AsyncUDPSocket::GetOption(Socket::Option opt, int* value) { | |
87 return socket_->GetOption(opt, value); | |
88 } | |
89 | |
90 int AsyncUDPSocket::SetOption(Socket::Option opt, int value) { | |
91 return socket_->SetOption(opt, value); | |
92 } | |
93 | |
94 int AsyncUDPSocket::GetError() const { | |
95 return socket_->GetError(); | |
96 } | |
97 | |
98 void AsyncUDPSocket::SetError(int error) { | |
99 return socket_->SetError(error); | |
100 } | |
101 | |
102 void AsyncUDPSocket::OnReadEvent(AsyncSocket* socket) { | |
103 RTC_DCHECK(socket_.get() == socket); | |
104 | |
105 SocketAddress remote_addr; | |
106 int64_t timestamp; | |
107 int len = socket_->RecvFrom(buf_, size_, &remote_addr, ×tamp); | |
108 if (len < 0) { | |
109 // An error here typically means we got an ICMP error in response to our | |
110 // send datagram, indicating the remote address was unreachable. | |
111 // When doing ICE, this kind of thing will often happen. | |
112 // TODO: Do something better like forwarding the error to the user. | |
113 SocketAddress local_addr = socket_->GetLocalAddress(); | |
114 LOG(LS_INFO) << "AsyncUDPSocket[" << local_addr.ToSensitiveString() << "] " | |
115 << "receive failed with error " << socket_->GetError(); | |
116 return; | |
117 } | |
118 | |
119 // TODO: Make sure that we got all of the packet. | |
120 // If we did not, then we should resize our buffer to be large enough. | |
121 SignalReadPacket( | |
122 this, buf_, static_cast<size_t>(len), remote_addr, | |
123 (timestamp > -1 ? PacketTime(timestamp, 0) : CreatePacketTime(0))); | |
124 } | |
125 | |
126 void AsyncUDPSocket::OnWriteEvent(AsyncSocket* socket) { | |
127 SignalReadyToSend(this); | |
128 } | |
129 | |
130 } // namespace rtc | |
OLD | NEW |