15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/*
25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle
35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004--2005, Google Inc.
45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without
65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met:
75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer.
105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer in the documentation
125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     and/or other materials provided with the distribution.
135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  3. The name of the author may not be used to endorse or promote products
145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     derived from this software without specific prior written permission.
155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */
275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "xmppsocket.h"
295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef HAVE_CONFIG_H
315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <config.h>
325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <errno.h>
355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/basicdefs.h"
365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/logging.h"
375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/thread.h"
385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef FEATURE_ENABLE_SSL
395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/ssladapter.h"
405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef USE_SSLSTREAM
435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/socketstream.h"
445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef FEATURE_ENABLE_SSL
455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/sslstreamadapter.h"
465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // FEATURE_ENABLE_SSL
475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // USE_SSLSTREAM
485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace buzz {
505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppSocket::XmppSocket(buzz::TlsOptions tls) : cricket_socket_(NULL),
525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                               tls_(tls) {
535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  state_ = buzz::AsyncSocket::STATE_CLOSED;
545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmppSocket::CreateCricketSocket(int family) {
575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::Thread* pth = talk_base::Thread::Current();
585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (family == AF_UNSPEC) {
595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    family = AF_INET;
605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::AsyncSocket* socket =
625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      pth->socketserver()->CreateAsyncSocket(family, SOCK_STREAM);
635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef USE_SSLSTREAM
645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef FEATURE_ENABLE_SSL
655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (tls_ != buzz::TLS_DISABLED) {
665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    socket = talk_base::SSLAdapter::Create(socket);
675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // FEATURE_ENABLE_SSL
695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket_socket_ = socket;
705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket_socket_->SignalReadEvent.connect(this, &XmppSocket::OnReadEvent);
715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket_socket_->SignalWriteEvent.connect(this, &XmppSocket::OnWriteEvent);
725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket_socket_->SignalConnectEvent.connect(this,
735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                              &XmppSocket::OnConnectEvent);
745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket_socket_->SignalCloseEvent.connect(this, &XmppSocket::OnCloseEvent);
755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else  // USE_SSLSTREAM
765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket_socket_ = socket;
775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  stream_ = new talk_base::SocketStream(cricket_socket_);
785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef FEATURE_ENABLE_SSL
795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (tls_ != buzz::TLS_DISABLED)
805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    stream_ = talk_base::SSLStreamAdapter::Create(stream_);
815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // FEATURE_ENABLE_SSL
825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  stream_->SignalEvent.connect(this, &XmppSocket::OnEvent);
835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // USE_SSLSTREAM
845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppSocket::~XmppSocket() {
875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  Close();
885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef USE_SSLSTREAM
895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  delete cricket_socket_;
905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else  // USE_SSLSTREAM
915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  delete stream_;
925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // USE_SSLSTREAM
935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef USE_SSLSTREAM
965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmppSocket::OnReadEvent(talk_base::AsyncSocket * socket) {
975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalRead();
985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmppSocket::OnWriteEvent(talk_base::AsyncSocket * socket) {
1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Write bytes if there are any
1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  while (buffer_.Length() != 0) {
1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int written = cricket_socket_->Send(buffer_.Data(), buffer_.Length());
1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (written > 0) {
1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      buffer_.Consume(written);
1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      continue;
1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!cricket_socket_->IsBlocking())
1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      LOG(LS_ERROR) << "Send error: " << cricket_socket_->GetError();
1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return;
1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmppSocket::OnConnectEvent(talk_base::AsyncSocket * socket) {
1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(FEATURE_ENABLE_SSL)
1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (state_ == buzz::AsyncSocket::STATE_TLS_CONNECTING) {
1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    state_ = buzz::AsyncSocket::STATE_TLS_OPEN;
1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalSSLConnected();
1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    OnWriteEvent(cricket_socket_);
1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return;
1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // !defined(FEATURE_ENABLE_SSL)
1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  state_ = buzz::AsyncSocket::STATE_OPEN;
1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalConnected();
1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmppSocket::OnCloseEvent(talk_base::AsyncSocket * socket, int error) {
1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalCloseEvent(error);
1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else  // USE_SSLSTREAM
1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid XmppSocket::OnEvent(talk_base::StreamInterface* stream,
1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                         int events, int err) {
1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if ((events & talk_base::SE_OPEN)) {
1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(FEATURE_ENABLE_SSL)
1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (state_ == buzz::AsyncSocket::STATE_TLS_CONNECTING) {
1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      state_ = buzz::AsyncSocket::STATE_TLS_OPEN;
1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      SignalSSLConnected();
1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      events |= talk_base::SE_WRITE;
1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else
1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    {
1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      state_ = buzz::AsyncSocket::STATE_OPEN;
1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      SignalConnected();
1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if ((events & talk_base::SE_READ))
1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalRead();
1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if ((events & talk_base::SE_WRITE)) {
1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Write bytes if there are any
1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    while (buffer_.Length() != 0) {
1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      talk_base::StreamResult result;
1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      size_t written;
1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      int error;
1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      result = stream_->Write(buffer_.Data(), buffer_.Length(),
1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              &written, &error);
1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      if (result == talk_base::SR_ERROR) {
1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        LOG(LS_ERROR) << "Send error: " << error;
1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        return;
1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      }
1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      if (result == talk_base::SR_BLOCK)
1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        return;
1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ASSERT(result == talk_base::SR_SUCCESS);
1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ASSERT(written > 0);
1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      buffer_.Shift(written);
1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if ((events & talk_base::SE_CLOSE))
1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalCloseEvent(err);
1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // USE_SSLSTREAM
1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbuzz::AsyncSocket::State XmppSocket::state() {
1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return state_;
1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbuzz::AsyncSocket::Error XmppSocket::error() {
1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return buzz::AsyncSocket::ERROR_NONE;
1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint XmppSocket::GetError() {
1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return 0;
1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool XmppSocket::Connect(const talk_base::SocketAddress& addr) {
1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (cricket_socket_ == NULL) {
1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    CreateCricketSocket(addr.family());
1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (cricket_socket_->Connect(addr) < 0) {
1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return cricket_socket_->IsBlocking();
1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool XmppSocket::Read(char * data, size_t len, size_t* len_read) {
1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef USE_SSLSTREAM
1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int read = cricket_socket_->Recv(data, len);
1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (read > 0) {
2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    *len_read = (size_t)read;
2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return true;
2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else  // USE_SSLSTREAM
2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::StreamResult result = stream_->Read(data, len, len_read, NULL);
2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (result == talk_base::SR_SUCCESS)
2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return true;
2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // USE_SSLSTREAM
2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return false;
2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool XmppSocket::Write(const char * data, size_t len) {
2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  buffer_.WriteBytes(data, len);
2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef USE_SSLSTREAM
2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  OnWriteEvent(cricket_socket_);
2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else  // USE_SSLSTREAM
2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  OnEvent(stream_, talk_base::SE_WRITE, 0);
2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // USE_SSLSTREAM
2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool XmppSocket::Close() {
2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (state_ != buzz::AsyncSocket::STATE_OPEN)
2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef USE_SSLSTREAM
2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (cricket_socket_->Close() == 0) {
2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    state_ = buzz::AsyncSocket::STATE_CLOSED;
2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalClosed();
2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return true;
2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return false;
2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else  // USE_SSLSTREAM
2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  state_ = buzz::AsyncSocket::STATE_CLOSED;
2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  stream_->Close();
2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalClosed();
2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // USE_SSLSTREAM
2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool XmppSocket::StartTls(const std::string & domainname) {
2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(FEATURE_ENABLE_SSL)
2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (tls_ == buzz::TLS_DISABLED)
2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifndef USE_SSLSTREAM
2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::SSLAdapter* ssl_adapter =
2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    static_cast<talk_base::SSLAdapter *>(cricket_socket_);
2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (ssl_adapter->StartSSL(domainname.c_str(), false) != 0)
2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else  // USE_SSLSTREAM
2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::SSLStreamAdapter* ssl_stream =
2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    static_cast<talk_base::SSLStreamAdapter *>(stream_);
2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (ssl_stream->StartSSLWithServer(domainname.c_str()) != 0)
2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // USE_SSLSTREAM
2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  state_ = buzz::AsyncSocket::STATE_TLS_CONNECTING;
2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else  // !defined(FEATURE_ENABLE_SSL)
2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return false;
2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif  // !defined(FEATURE_ENABLE_SSL)
2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}  // namespace buzz
2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
263