Home | History | Annotate | Download | only in base
      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 
     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 
     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 
     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 
     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::Time());
     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::Time());
     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   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 
    124 void AsyncUDPSocket::OnWriteEvent(AsyncSocket* socket) {
    125   SignalReadyToSend(this);
    126 }
    127 
    128 }  // namespace rtc
    129