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