• 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   return socket_->Send(pv, cb);
64 }
65 
SendTo(const void * pv,size_t cb,const SocketAddress & addr,const rtc::PacketOptions & options)66 int AsyncUDPSocket::SendTo(const void *pv, size_t cb,
67                            const SocketAddress& addr,
68                            const rtc::PacketOptions& options) {
69   return socket_->SendTo(pv, cb, addr);
70 }
71 
Close()72 int AsyncUDPSocket::Close() {
73   return socket_->Close();
74 }
75 
GetState() const76 AsyncUDPSocket::State AsyncUDPSocket::GetState() const {
77   return STATE_BOUND;
78 }
79 
GetOption(Socket::Option opt,int * value)80 int AsyncUDPSocket::GetOption(Socket::Option opt, int* value) {
81   return socket_->GetOption(opt, value);
82 }
83 
SetOption(Socket::Option opt,int value)84 int AsyncUDPSocket::SetOption(Socket::Option opt, int value) {
85   return socket_->SetOption(opt, value);
86 }
87 
GetError() const88 int AsyncUDPSocket::GetError() const {
89   return socket_->GetError();
90 }
91 
SetError(int error)92 void AsyncUDPSocket::SetError(int error) {
93   return socket_->SetError(error);
94 }
95 
OnReadEvent(AsyncSocket * socket)96 void AsyncUDPSocket::OnReadEvent(AsyncSocket* socket) {
97   ASSERT(socket_.get() == socket);
98 
99   SocketAddress remote_addr;
100   int len = socket_->RecvFrom(buf_, size_, &remote_addr);
101   if (len < 0) {
102     // An error here typically means we got an ICMP error in response to our
103     // send datagram, indicating the remote address was unreachable.
104     // When doing ICE, this kind of thing will often happen.
105     // TODO: Do something better like forwarding the error to the user.
106     SocketAddress local_addr = socket_->GetLocalAddress();
107     LOG(LS_INFO) << "AsyncUDPSocket[" << local_addr.ToSensitiveString() << "] "
108                  << "receive failed with error " << socket_->GetError();
109     return;
110   }
111 
112   // TODO: Make sure that we got all of the packet.
113   // If we did not, then we should resize our buffer to be large enough.
114   SignalReadPacket(this, buf_, static_cast<size_t>(len), remote_addr,
115                    CreatePacketTime(0));
116 }
117 
OnWriteEvent(AsyncSocket * socket)118 void AsyncUDPSocket::OnWriteEvent(AsyncSocket* socket) {
119   SignalReadyToSend(this);
120 }
121 
122 }  // namespace rtc
123