move xmpp and p2p to webrtc
Create a copy of talk/xmpp and talk/p2p under webrtc/libjingle/xmpp and
webrtc/p2p. Also makes libjingle use those version instead of the one in the talk folder.

BUG=3379

Review URL: https://webrtc-codereview.appspot.com/26999004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7549 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/p2p/base/stunrequest.cc b/webrtc/p2p/base/stunrequest.cc
new file mode 100644
index 0000000..65eb027
--- /dev/null
+++ b/webrtc/p2p/base/stunrequest.cc
@@ -0,0 +1,193 @@
+/*
+ *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/p2p/base/stunrequest.h"
+
+#include "webrtc/base/common.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+
+namespace cricket {
+
+const uint32 MSG_STUN_SEND = 1;
+
+const int MAX_SENDS = 9;
+const int DELAY_UNIT = 100;  // 100 milliseconds
+const int DELAY_MAX_FACTOR = 16;
+
+StunRequestManager::StunRequestManager(rtc::Thread* thread)
+    : thread_(thread) {
+}
+
+StunRequestManager::~StunRequestManager() {
+  while (requests_.begin() != requests_.end()) {
+    StunRequest *request = requests_.begin()->second;
+    requests_.erase(requests_.begin());
+    delete request;
+  }
+}
+
+void StunRequestManager::Send(StunRequest* request) {
+  SendDelayed(request, 0);
+}
+
+void StunRequestManager::SendDelayed(StunRequest* request, int delay) {
+  request->set_manager(this);
+  ASSERT(requests_.find(request->id()) == requests_.end());
+  request->Construct();
+  requests_[request->id()] = request;
+  thread_->PostDelayed(delay, request, MSG_STUN_SEND, NULL);
+}
+
+void StunRequestManager::Remove(StunRequest* request) {
+  ASSERT(request->manager() == this);
+  RequestMap::iterator iter = requests_.find(request->id());
+  if (iter != requests_.end()) {
+    ASSERT(iter->second == request);
+    requests_.erase(iter);
+    thread_->Clear(request);
+  }
+}
+
+void StunRequestManager::Clear() {
+  std::vector<StunRequest*> requests;
+  for (RequestMap::iterator i = requests_.begin(); i != requests_.end(); ++i)
+    requests.push_back(i->second);
+
+  for (uint32 i = 0; i < requests.size(); ++i) {
+    // StunRequest destructor calls Remove() which deletes requests
+    // from |requests_|.
+    delete requests[i];
+  }
+}
+
+bool StunRequestManager::CheckResponse(StunMessage* msg) {
+  RequestMap::iterator iter = requests_.find(msg->transaction_id());
+  if (iter == requests_.end())
+    return false;
+
+  StunRequest* request = iter->second;
+  if (msg->type() == GetStunSuccessResponseType(request->type())) {
+    request->OnResponse(msg);
+  } else if (msg->type() == GetStunErrorResponseType(request->type())) {
+    request->OnErrorResponse(msg);
+  } else {
+    LOG(LERROR) << "Received response with wrong type: " << msg->type()
+                << " (expecting "
+                << GetStunSuccessResponseType(request->type()) << ")";
+    return false;
+  }
+
+  delete request;
+  return true;
+}
+
+bool StunRequestManager::CheckResponse(const char* data, size_t size) {
+  // Check the appropriate bytes of the stream to see if they match the
+  // transaction ID of a response we are expecting.
+
+  if (size < 20)
+    return false;
+
+  std::string id;
+  id.append(data + kStunTransactionIdOffset, kStunTransactionIdLength);
+
+  RequestMap::iterator iter = requests_.find(id);
+  if (iter == requests_.end())
+    return false;
+
+  // Parse the STUN message and continue processing as usual.
+
+  rtc::ByteBuffer buf(data, size);
+  rtc::scoped_ptr<StunMessage> response(iter->second->msg_->CreateNew());
+  if (!response->Read(&buf))
+    return false;
+
+  return CheckResponse(response.get());
+}
+
+StunRequest::StunRequest()
+    : count_(0), timeout_(false), manager_(0),
+      msg_(new StunMessage()), tstamp_(0) {
+  msg_->SetTransactionID(
+      rtc::CreateRandomString(kStunTransactionIdLength));
+}
+
+StunRequest::StunRequest(StunMessage* request)
+    : count_(0), timeout_(false), manager_(0),
+      msg_(request), tstamp_(0) {
+  msg_->SetTransactionID(
+      rtc::CreateRandomString(kStunTransactionIdLength));
+}
+
+StunRequest::~StunRequest() {
+  ASSERT(manager_ != NULL);
+  if (manager_) {
+    manager_->Remove(this);
+    manager_->thread_->Clear(this);
+  }
+  delete msg_;
+}
+
+void StunRequest::Construct() {
+  if (msg_->type() == 0) {
+    Prepare(msg_);
+    ASSERT(msg_->type() != 0);
+  }
+}
+
+int StunRequest::type() {
+  ASSERT(msg_ != NULL);
+  return msg_->type();
+}
+
+const StunMessage* StunRequest::msg() const {
+  return msg_;
+}
+
+uint32 StunRequest::Elapsed() const {
+  return rtc::TimeSince(tstamp_);
+}
+
+
+void StunRequest::set_manager(StunRequestManager* manager) {
+  ASSERT(!manager_);
+  manager_ = manager;
+}
+
+void StunRequest::OnMessage(rtc::Message* pmsg) {
+  ASSERT(manager_ != NULL);
+  ASSERT(pmsg->message_id == MSG_STUN_SEND);
+
+  if (timeout_) {
+    OnTimeout();
+    delete this;
+    return;
+  }
+
+  tstamp_ = rtc::Time();
+
+  rtc::ByteBuffer buf;
+  msg_->Write(&buf);
+  manager_->SignalSendPacket(buf.Data(), buf.Length(), this);
+
+  int delay = GetNextDelay();
+  manager_->thread_->PostDelayed(delay, this, MSG_STUN_SEND, NULL);
+}
+
+int StunRequest::GetNextDelay() {
+  int delay = DELAY_UNIT * rtc::_min(1 << count_, DELAY_MAX_FACTOR);
+  count_ += 1;
+  if (count_ == MAX_SENDS)
+    timeout_ = true;
+  return delay;
+}
+
+}  // namespace cricket