• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/logging.h"
13 
14 namespace rtc {
15 
16 static const int BUF_SIZE = 64 * 1024;
17 
Create(AsyncSocket * socket,const SocketAddress & bind_address)18 AsyncUDPSocket* AsyncUDPSocket::Create(
19     AsyncSocket* socket,
20     const SocketAddress& bind_address) {
21   scoped_ptr<AsyncSocket> owned_socket(socket);
22   if (socket->Bind(bind_address) < 0) {
23     LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError();
24     return NULL;
25   }
26   return new AsyncUDPSocket(owned_socket.release());
27 }
28 
Create(SocketFactory * factory,const SocketAddress & bind_address)29 AsyncUDPSocket* AsyncUDPSocket::Create(SocketFactory* factory,
30                                        const SocketAddress& bind_address) {
31   AsyncSocket* socket =
32       factory->CreateAsyncSocket(bind_address.family(), SOCK_DGRAM);
33   if (!socket)
34     return NULL;
35   return Create(socket, bind_address);
36 }
37 
AsyncUDPSocket(AsyncSocket * socket)38 AsyncUDPSocket::AsyncUDPSocket(AsyncSocket* socket)
39     : socket_(socket) {
40   ASSERT(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 
~AsyncUDPSocket()49 AsyncUDPSocket::~AsyncUDPSocket() {
50   delete [] buf_;
51 }
52 
GetLocalAddress() const53 SocketAddress AsyncUDPSocket::GetLocalAddress() const {
54   return socket_->GetLocalAddress();
55 }
56 
GetRemoteAddress() const57 SocketAddress AsyncUDPSocket::GetRemoteAddress() const {
58   return socket_->GetRemoteAddress();
59 }
60 
Send(const void * pv,size_t cb,const rtc::PacketOptions & options)61 int AsyncUDPSocket::Send(const void *pv, size_t cb,
62                          const rtc::PacketOptions& options) {
63   rtc::SentPacket sent_packet(options.packet_id, rtc::Time());
64   int ret = socket_->Send(pv, cb);
65   SignalSentPacket(this, sent_packet);
66   return ret;
67 }
68 
SendTo(const void * pv,size_t cb,const SocketAddress & addr,const rtc::PacketOptions & options)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::Time());
73   int ret = socket_->SendTo(pv, cb, addr);
74   SignalSentPacket(this, sent_packet);
75   return ret;
76 }
77 
Close()78 int AsyncUDPSocket::Close() {
79   return socket_->Close();
80 }
81 
GetState() const82 AsyncUDPSocket::State AsyncUDPSocket::GetState() const {
83   return STATE_BOUND;
84 }
85 
GetOption(Socket::Option opt,int * value)86 int AsyncUDPSocket::GetOption(Socket::Option opt, int* value) {
87   return socket_->GetOption(opt, value);
88 }
89 
SetOption(Socket::Option opt,int value)90 int AsyncUDPSocket::SetOption(Socket::Option opt, int value) {
91   return socket_->SetOption(opt, value);
92 }
93 
GetError() const94 int AsyncUDPSocket::GetError() const {
95   return socket_->GetError();
96 }
97 
SetError(int error)98 void AsyncUDPSocket::SetError(int error) {
99   return socket_->SetError(error);
100 }
101 
OnReadEvent(AsyncSocket * socket)102 void AsyncUDPSocket::OnReadEvent(AsyncSocket* socket) {
103   ASSERT(socket_.get() == socket);
104 
105   SocketAddress remote_addr;
106   int len = socket_->RecvFrom(buf_, size_, &remote_addr);
107   if (len < 0) {
108     // An error here typically means we got an ICMP error in response to our
109     // send datagram, indicating the remote address was unreachable.
110     // When doing ICE, this kind of thing will often happen.
111     // TODO: Do something better like forwarding the error to the user.
112     SocketAddress local_addr = socket_->GetLocalAddress();
113     LOG(LS_INFO) << "AsyncUDPSocket[" << local_addr.ToSensitiveString() << "] "
114                  << "receive failed with error " << socket_->GetError();
115     return;
116   }
117 
118   // TODO: Make sure that we got all of the packet.
119   // If we did not, then we should resize our buffer to be large enough.
120   SignalReadPacket(this, buf_, static_cast<size_t>(len), remote_addr,
121                    CreatePacketTime(0));
122 }
123 
OnWriteEvent(AsyncSocket * socket)124 void AsyncUDPSocket::OnWriteEvent(AsyncSocket* socket) {
125   SignalReadyToSend(this);
126 }
127 
128 }  // namespace rtc
129