Home | History | Annotate | Download | only in p2p
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/renderer_host/p2p/socket_host.h"
      6 
      7 #include "base/sys_byteorder.h"
      8 #include "content/browser/renderer_host/p2p/socket_host_tcp.h"
      9 #include "content/browser/renderer_host/p2p/socket_host_tcp_server.h"
     10 #include "content/browser/renderer_host/p2p/socket_host_udp.h"
     11 
     12 namespace {
     13 const uint32 kStunMagicCookie = 0x2112A442;
     14 }  // namespace
     15 
     16 namespace content {
     17 
     18 P2PSocketHost::P2PSocketHost(IPC::Sender* message_sender, int id)
     19     : message_sender_(message_sender),
     20       id_(id),
     21       state_(STATE_UNINITIALIZED) {
     22 }
     23 
     24 P2PSocketHost::~P2PSocketHost() { }
     25 
     26 // Verifies that the packet |data| has a valid STUN header.
     27 // static
     28 bool P2PSocketHost::GetStunPacketType(
     29     const char* data, int data_size, StunMessageType* type) {
     30 
     31   if (data_size < kStunHeaderSize)
     32     return false;
     33 
     34   uint32 cookie = base::NetToHost32(*reinterpret_cast<const uint32*>(data + 4));
     35   if (cookie != kStunMagicCookie)
     36     return false;
     37 
     38   uint16 length = base::NetToHost16(*reinterpret_cast<const uint16*>(data + 2));
     39   if (length != data_size - kStunHeaderSize)
     40     return false;
     41 
     42   int message_type = base::NetToHost16(*reinterpret_cast<const uint16*>(data));
     43 
     44   // Verify that the type is known:
     45   switch (message_type) {
     46     case STUN_BINDING_REQUEST:
     47     case STUN_BINDING_RESPONSE:
     48     case STUN_BINDING_ERROR_RESPONSE:
     49     case STUN_SHARED_SECRET_REQUEST:
     50     case STUN_SHARED_SECRET_RESPONSE:
     51     case STUN_SHARED_SECRET_ERROR_RESPONSE:
     52     case STUN_ALLOCATE_REQUEST:
     53     case STUN_ALLOCATE_RESPONSE:
     54     case STUN_ALLOCATE_ERROR_RESPONSE:
     55     case STUN_SEND_REQUEST:
     56     case STUN_SEND_RESPONSE:
     57     case STUN_SEND_ERROR_RESPONSE:
     58     case STUN_DATA_INDICATION:
     59       *type = static_cast<StunMessageType>(message_type);
     60       return true;
     61 
     62     default:
     63       return false;
     64   }
     65 }
     66 
     67 // static
     68 bool P2PSocketHost::IsRequestOrResponse(StunMessageType type) {
     69   return type == STUN_BINDING_REQUEST || type == STUN_BINDING_RESPONSE ||
     70       type == STUN_ALLOCATE_REQUEST || type == STUN_ALLOCATE_RESPONSE;
     71 }
     72 
     73 // static
     74 P2PSocketHost* P2PSocketHost::Create(
     75     IPC::Sender* message_sender, int id, P2PSocketType type,
     76     net::URLRequestContextGetter* url_context) {
     77   switch (type) {
     78     case P2P_SOCKET_UDP:
     79       return new P2PSocketHostUdp(message_sender, id);
     80 
     81     case P2P_SOCKET_TCP_SERVER:
     82       return new P2PSocketHostTcpServer(
     83           message_sender, id, P2P_SOCKET_TCP_CLIENT);
     84 
     85     case P2P_SOCKET_STUN_TCP_SERVER:
     86       return new P2PSocketHostTcpServer(
     87           message_sender, id, P2P_SOCKET_STUN_TCP_CLIENT);
     88 
     89     case P2P_SOCKET_TCP_CLIENT:
     90     case P2P_SOCKET_SSLTCP_CLIENT:
     91     case P2P_SOCKET_TLS_CLIENT:
     92       return new P2PSocketHostTcp(message_sender, id, type, url_context);
     93 
     94     case P2P_SOCKET_STUN_TCP_CLIENT:
     95     case P2P_SOCKET_STUN_SSLTCP_CLIENT:
     96     case P2P_SOCKET_STUN_TLS_CLIENT:
     97       return new P2PSocketHostStunTcp(message_sender, id, type, url_context);
     98   }
     99 
    100   NOTREACHED();
    101   return NULL;
    102 }
    103 
    104 }  // namespace content
    105