⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 relayserver.cxx

📁 由GOOGLE的JINGLE项目中移植的网络库
💻 CXX
📖 第 1 页 / 共 2 页
字号:
  // Now that we have a connection, this other method takes over.  HandleStunAllocate(int_conn, request);}void RelayServer::HandleStun(    RelayServerConnection* int_conn, const char* bytes, size_t size) {  // Make sure this is a valid STUN request.  StunMessage request;  std::string username;  if (!HandleStun(bytes, size, int_conn->addr_pair().source(),                  int_conn->socket(), &username, &request))    return;  // Make sure the username is the one were were expecting.  if (username != int_conn->binding()->username()) {    int_conn->SendStunError(request, 430, "Stale Credentials");    return;  }  // TODO: Check the HMAC.  // Send this request to the appropriate handler.  if (request.type() == STUN_SEND_REQUEST)    HandleStunSend(int_conn, request);  else if (request.type() == STUN_ALLOCATE_REQUEST)    HandleStunAllocate(int_conn, request);  else    int_conn->SendStunError(request, 600, "Operation Not Supported");}void RelayServer::HandleStunAllocate(    RelayServerConnection* int_conn, const StunMessage& request) {  // Create a response message that includes an address with which external  // clients can communicate.  StunMessage response;  response.SetType(STUN_ALLOCATE_RESPONSE);  response.SetTransactionID(request.transaction_id());  StunByteStringAttribute* magic_cookie_attr =      StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);  magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),                               int_conn->binding()->magic_cookie().size());  response.AddAttribute(magic_cookie_attr);  size_t index = rand() % external_sockets_.size();  SocketAddress ext_addr = external_sockets_[index]->GetLocalAddress();  StunAddressAttribute* addr_attr =      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);  addr_attr->SetFamily(1);  addr_attr->SetIP(ext_addr.ip());  addr_attr->SetPort(ext_addr.port());  response.AddAttribute(addr_attr);  StunUInt32Attribute* res_lifetime_attr =      StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);  res_lifetime_attr->SetValue(int_conn->binding()->lifetime() / 1000);  response.AddAttribute(res_lifetime_attr);  // TODO: Support transport-prefs (preallocate RTCP port).  // TODO: Support bandwidth restrictions.  // TODO: Add message integrity check.  // Send a response to the caller.  int_conn->SendStun(response);}void RelayServer::HandleStunSend(    RelayServerConnection* int_conn, const StunMessage& request) {  const StunAddressAttribute* addr_attr =      request.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);  if (!addr_attr) {    int_conn->SendStunError(request, 400, "Bad Request");    return;  }  const StunByteStringAttribute* data_attr =      request.GetByteString(STUN_ATTR_DATA);  if (!data_attr) {    int_conn->SendStunError(request, 400, "Bad Request");    return;  }  SocketAddress ext_addr(addr_attr->ip(), addr_attr->port());  RelayServerConnection* ext_conn =      int_conn->binding()->GetExternalConnection(ext_addr);  if (!ext_conn) {    // This happens very often and is not an error.    //std::cerr << "Dropping packet: no external connection" << std::endl;    return;  }  ext_conn->Send(data_attr->bytes(), data_attr->length());  const StunUInt32Attribute* options_attr =      request.GetUInt32(STUN_ATTR_OPTIONS);  if (options_attr && (options_attr->value() & 0x01 != 0)) {    int_conn->set_default_destination(ext_addr);    int_conn->Lock();    StunMessage response;    response.SetType(STUN_SEND_RESPONSE);    response.SetTransactionID(request.transaction_id());    StunByteStringAttribute* magic_cookie_attr =        StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);    magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),                                 int_conn->binding()->magic_cookie().size());    response.AddAttribute(magic_cookie_attr);    StunUInt32Attribute* options2_attr =      StunAttribute::CreateUInt32(cricket::STUN_ATTR_OPTIONS);    options2_attr->SetValue(0x01);    response.AddAttribute(options2_attr);        int_conn->SendStun(response);  }}void RelayServer::AddConnection(RelayServerConnection* conn) {  assert(connections_.find(conn->addr_pair()) == connections_.end());  connections_[conn->addr_pair()] = conn;}void RelayServer::RemoveConnection(RelayServerConnection* conn) {  ConnectionMap::iterator iter = connections_.find(conn->addr_pair());  assert(iter != connections_.end());  connections_.erase(iter);}void RelayServer::RemoveBinding(RelayServerBinding* binding) {  BindingMap::iterator iter = bindings_.find(binding->username());  assert(iter != bindings_.end());  bindings_.erase(iter);///  std::cout << "Removed a binding: " << bindings_.size() << " remaining" << std::endl;}void RelayServer::OnTimeout(RelayServerBinding* binding) {  // This call will result in all of the necessary clean-up.  delete binding;}RelayServerConnection::RelayServerConnection(    RelayServerBinding* binding, const SocketAddressPair& addrs,    AsyncPacketSocket* socket)  : binding_(binding), addr_pair_(addrs), socket_(socket), locked_(false) {  // The creation of a new connection constitutes a use of the binding.  binding_->NoteUsed();}RelayServerConnection::~RelayServerConnection() {  // Remove this connection from the server's map (if it exists there).  binding_->server()->RemoveConnection(this);}void RelayServerConnection::Send(const char* data, size_t size) {  // Note that the binding has been used again.  binding_->NoteUsed();  cricket::Send(socket_, data, size, addr_pair_.source());}void RelayServerConnection::Send(    const char* data, size_t size, const SocketAddress& from_addr) {  // If the from address is known to the client, we don't need to send it.  if (locked() && (from_addr == default_dest_)) {    Send(data, size);    return;  }  // Wrap the given data in a data-indication packet.  StunMessage msg;  msg.SetType(STUN_DATA_INDICATION);  msg.SetTransactionID("0000000000000000");  StunByteStringAttribute* magic_cookie_attr =      StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);  magic_cookie_attr->CopyBytes(binding_->magic_cookie().c_str(),                               binding_->magic_cookie().size());  msg.AddAttribute(magic_cookie_attr);  StunAddressAttribute* addr_attr =      StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);  addr_attr->SetFamily(1);  addr_attr->SetIP(from_addr.ip());  addr_attr->SetPort(from_addr.port());  msg.AddAttribute(addr_attr);  StunByteStringAttribute* data_attr =      StunAttribute::CreateByteString(STUN_ATTR_DATA);  assert(size <= 65536);  data_attr->CopyBytes(data, uint16(size));  msg.AddAttribute(data_attr);  SendStun(msg);}void RelayServerConnection::SendStun(const StunMessage& msg) {  // Note that the binding has been used again.  binding_->NoteUsed();  cricket::SendStun(msg, socket_, addr_pair_.source());}void RelayServerConnection::SendStunError(      const StunMessage& request, int error_code, const char* error_desc) {  // An error does not indicate use.  If no legitimate use off the binding  // occurs, we want it to be cleaned up even if errors are still occuring.  cricket::SendStunError(      request, socket_, addr_pair_.source(), error_code, error_desc,      binding_->magic_cookie());}void RelayServerConnection::Lock() {  locked_ = true;}void RelayServerConnection::Unlock() {  locked_ = false;}// IDs used for posted messages:const uint32 MSG_LIFETIME_TIMER = 1;RelayServerBinding::RelayServerBinding(    RelayServer* server, const std::string& username,    const std::string& password, uint32 lifetime)  : server_(server), username_(username), password_(password),    lifetime_(lifetime) {  // For now, every connection uses the standard magic cookie value.  magic_cookie_.append(      reinterpret_cast<const char*>(STUN_MAGIC_COOKIE_VALUE), 4);  // Initialize the last-used time to now.  NoteUsed();  // Set the first timeout check.  server_->thread()->PostDelayed(lifetime_, this, MSG_LIFETIME_TIMER);}RelayServerBinding::~RelayServerBinding() {  // Clear the outstanding timeout check.  server_->thread()->Clear(this);
  size_t i;  // Clean up all of the connections.  for (i = 0; i < internal_connections_.size(); ++i)    delete internal_connections_[i];  for (i = 0; i < external_connections_.size(); ++i)    delete external_connections_[i];  // Remove this binding from the server's map.  server_->RemoveBinding(this);}void RelayServerBinding::AddInternalConnection(RelayServerConnection* conn) {  internal_connections_.push_back(conn);}void RelayServerBinding::AddExternalConnection(RelayServerConnection* conn) {  external_connections_.push_back(conn);}void RelayServerBinding::NoteUsed() {  last_used_ = GetMillisecondCount();}bool RelayServerBinding::HasMagicCookie(const char* bytes, size_t size) const {  if (size < 24 + magic_cookie_.size()) {    return false;  } else {    return 0 == memcmp(        bytes + 24, magic_cookie_.c_str(), magic_cookie_.size());  }}RelayServerConnection* RelayServerBinding::GetInternalConnection(    const SocketAddress& ext_addr) {  // Look for an internal connection that is locked to this address.  for (size_t i = 0; i < internal_connections_.size(); ++i) {    if (internal_connections_[i]->locked() &&        (ext_addr == internal_connections_[i]->default_destination()))      return internal_connections_[i];  }  // If one was not found, we send to the first connection.  assert(internal_connections_.size() > 0);  return internal_connections_[0];}RelayServerConnection* RelayServerBinding::GetExternalConnection(    const SocketAddress& ext_addr) {  for (size_t i = 0; i < external_connections_.size(); ++i) {    if (ext_addr == external_connections_[i]->addr_pair().source())      return external_connections_[i];  }  return 0;}void RelayServerBinding::OnMessage(Message *pmsg) {  if (pmsg->message_id == MSG_LIFETIME_TIMER) {    assert(!pmsg->pdata);    // If the lifetime timeout has been exceeded, then send a signal.    // Otherwise, just keep waiting.    if (GetMillisecondCount() >= last_used_ + lifetime_) {      SignalTimeout(this);    } else {      server_->thread()->PostDelayed(lifetime_, this, MSG_LIFETIME_TIMER);    }  } else {    assert(false);  }}} // namespace cricket

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -