147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/asynctcpsocket.h" 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string.h> 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/byteorder.h" 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h" 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/logging.h" 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX) 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <errno.h> 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_POSIX 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const size_t kMaxPacketSize = 64 * 1024; 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef uint16 PacketLength; 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const size_t kPacketLenSize = sizeof(PacketLength); 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const size_t kBufSize = kMaxPacketSize + kPacketLenSize; 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const int kListenBacklog = 5; 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Binds and connects |socket| 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncSocket* AsyncTCPSocketBase::ConnectSocket( 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org rtc::AsyncSocket* socket, 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const rtc::SocketAddress& bind_address, 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const rtc::SocketAddress& remote_address) { 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org rtc::scoped_ptr<rtc::AsyncSocket> owned_socket(socket); 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (socket->Bind(bind_address) < 0) { 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError(); 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return NULL; 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (socket->Connect(remote_address) < 0) { 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Connect() failed with error " << socket->GetError(); 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return NULL; 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return owned_socket.release(); 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen, 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t max_packet_size) 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : socket_(socket), 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org listen_(listen), 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org insize_(max_packet_size), 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org inpos_(0), 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org outsize_(max_packet_size), 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org outpos_(0) { 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org inbuf_ = new char[insize_]; 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org outbuf_ = new char[outsize_]; 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(socket_.get() != NULL); 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_->SignalConnectEvent.connect( 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org this, &AsyncTCPSocketBase::OnConnectEvent); 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent); 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent); 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent); 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (listen_) { 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (socket_->Listen(kListenBacklog) < 0) { 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError(); 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncTCPSocketBase::~AsyncTCPSocketBase() { 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete [] inbuf_; 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete [] outbuf_; 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress AsyncTCPSocketBase::GetLocalAddress() const { 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->GetLocalAddress(); 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress AsyncTCPSocketBase::GetRemoteAddress() const { 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->GetRemoteAddress(); 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint AsyncTCPSocketBase::Close() { 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->Close(); 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncTCPSocket::State AsyncTCPSocketBase::GetState() const { 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (socket_->GetState()) { 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case Socket::CS_CLOSED: 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return STATE_CLOSED; 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case Socket::CS_CONNECTING: 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (listen_) { 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return STATE_BOUND; 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return STATE_CONNECTING; 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case Socket::CS_CONNECTED: 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return STATE_CONNECTED; 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(false); 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return STATE_CLOSED; 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint AsyncTCPSocketBase::GetOption(Socket::Option opt, int* value) { 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->GetOption(opt, value); 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint AsyncTCPSocketBase::SetOption(Socket::Option opt, int value) { 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->SetOption(opt, value); 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint AsyncTCPSocketBase::GetError() const { 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->GetError(); 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncTCPSocketBase::SetError(int error) { 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_->SetError(error); 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint AsyncTCPSocketBase::SendTo(const void *pv, size_t cb, 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const SocketAddress& addr, 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const rtc::PacketOptions& options) { 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (addr == GetRemoteAddress()) 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return Send(pv, cb, options); 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(false); 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_->SetError(ENOTCONN); 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint AsyncTCPSocketBase::SendRaw(const void * pv, size_t cb) { 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (outpos_ + cb > outsize_) { 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_->SetError(EMSGSIZE); 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memcpy(outbuf_ + outpos_, pv, cb); 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org outpos_ += cb; 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return FlushOutBuffer(); 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint AsyncTCPSocketBase::FlushOutBuffer() { 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int res = socket_->Send(outbuf_, outpos_); 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (res <= 0) { 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return res; 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (static_cast<size_t>(res) <= outpos_) { 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org outpos_ -= res; 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(false); 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (outpos_ > 0) { 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memmove(outbuf_, outbuf_ + res, outpos_); 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return res; 16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncTCPSocketBase::AppendToOutBuffer(const void* pv, size_t cb) { 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(outpos_ + cb < outsize_); 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memcpy(outbuf_ + outpos_, pv, cb); 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org outpos_ += cb; 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncTCPSocketBase::OnConnectEvent(AsyncSocket* socket) { 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SignalConnect(this); 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncTCPSocketBase::OnReadEvent(AsyncSocket* socket) { 17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(socket_.get() == socket); 17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (listen_) { 18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org rtc::SocketAddress address; 18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org rtc::AsyncSocket* new_socket = socket->Accept(&address); 18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!new_socket) { 18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Do something better like forwarding the error 18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // to the user. 18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError(); 18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HandleIncomingConnection(new_socket); 19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Prime a read event in case data is waiting. 19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org new_socket->SignalReadEvent(new_socket); 19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int len = socket_->Recv(inbuf_ + inpos_, insize_ - inpos_); 19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (len < 0) { 19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO: Do something better like forwarding the error to the user. 19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!socket_->IsBlocking()) { 19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError(); 20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org inpos_ += len; 20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ProcessInput(inbuf_, &inpos_); 20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (inpos_ >= insize_) { 20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "input buffer overflow"; 21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(false); 21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org inpos_ = 0; 21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) { 21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(socket_.get() == socket); 21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (outpos_ > 0) { 22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FlushOutBuffer(); 22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (outpos_ == 0) { 22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SignalReadyToSend(this); 22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncTCPSocketBase::OnCloseEvent(AsyncSocket* socket, int error) { 22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SignalClose(this, error); 23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// AsyncTCPSocket 23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Binds and connects |socket| and creates AsyncTCPSocket for 23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// it. Takes ownership of |socket|. Returns NULL if bind() or 23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// connect() fail (|socket| is destroyed in that case). 23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncTCPSocket* AsyncTCPSocket::Create( 23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocket* socket, 23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const SocketAddress& bind_address, 23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const SocketAddress& remote_address) { 24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return new AsyncTCPSocket(AsyncTCPSocketBase::ConnectSocket( 24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket, bind_address, remote_address), false); 24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncTCPSocket::AsyncTCPSocket(AsyncSocket* socket, bool listen) 24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : AsyncTCPSocketBase(socket, listen, kBufSize) { 24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint AsyncTCPSocket::Send(const void *pv, size_t cb, 24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const rtc::PacketOptions& options) { 25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (cb > kBufSize) { 25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EMSGSIZE); 25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If we are blocking on send, then silently drop this packet 25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!IsOutBufferEmpty()) 25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return static_cast<int>(cb); 25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PacketLength pkt_len = HostToNetwork16(static_cast<PacketLength>(cb)); 26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AppendToOutBuffer(&pkt_len, kPacketLenSize); 26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AppendToOutBuffer(pv, cb); 26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int res = FlushOutBuffer(); 26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (res <= 0) { 26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // drop packet if we made no progress 26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ClearOutBuffer(); 26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return res; 26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // We claim to have sent the whole thing, even if we only sent partial 27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return static_cast<int>(cb); 27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncTCPSocket::ProcessInput(char * data, size_t* len) { 27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SocketAddress remote_addr(GetRemoteAddress()); 27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org while (true) { 27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (*len < kPacketLenSize) 27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PacketLength pkt_len = rtc::GetBE16(data); 28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (*len < kPacketLenSize + pkt_len) 28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SignalReadPacket(this, data + kPacketLenSize, pkt_len, remote_addr, 28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CreatePacketTime(0)); 28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *len -= kPacketLenSize + pkt_len; 28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (*len > 0) { 29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memmove(data, data + kPacketLenSize + pkt_len, *len); 29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncTCPSocket::HandleIncomingConnection(AsyncSocket* socket) { 29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SignalNewConnection(this, new AsyncTCPSocket(socket, false)); 29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 300