~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/googletalk/libjingle/talk/p2p/base/stunserver.cc

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * libjingle
3
 
 * Copyright 2004--2005, Google Inc.
4
 
 *
5
 
 * Redistribution and use in source and binary forms, with or without
6
 
 * modification, are permitted provided that the following conditions are met:
7
 
 *
8
 
 *  1. Redistributions of source code must retain the above copyright notice,
9
 
 *     this list of conditions and the following disclaimer.
10
 
 *  2. Redistributions in binary form must reproduce the above copyright notice,
11
 
 *     this list of conditions and the following disclaimer in the documentation
12
 
 *     and/or other materials provided with the distribution.
13
 
 *  3. The name of the author may not be used to endorse or promote products
14
 
 *     derived from this software without specific prior written permission.
15
 
 *
16
 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
 
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 
 */
27
 
 
28
 
#ifdef POSIX
29
 
#include <errno.h>
30
 
#endif  // POSIX
31
 
 
32
 
#include "talk/p2p/base/stunserver.h"
33
 
#include "talk/base/bytebuffer.h"
34
 
#include "talk/base/logging.h"
35
 
 
36
 
namespace cricket {
37
 
 
38
 
StunServer::StunServer(talk_base::AsyncUDPSocket* socket) : socket_(socket) {
39
 
  socket_->SignalReadPacket.connect(this, &StunServer::OnPacket);
40
 
}
41
 
 
42
 
StunServer::~StunServer() {
43
 
  socket_->SignalReadPacket.disconnect(this);
44
 
}
45
 
 
46
 
void StunServer::OnPacket(
47
 
    talk_base::AsyncPacketSocket* socket, const char* buf, size_t size,
48
 
    const talk_base::SocketAddress& remote_addr) {
49
 
 
50
 
  // TODO: If appropriate, look for the magic cookie before parsing.
51
 
 
52
 
  // Parse the STUN message.
53
 
  talk_base::ByteBuffer bbuf(buf, size);
54
 
  StunMessage msg;
55
 
  if (!msg.Read(&bbuf)) {
56
 
    SendErrorResponse(msg, remote_addr, 400, "Bad Request");
57
 
    return;
58
 
  }
59
 
 
60
 
  // TODO: If this is UDP, then we shouldn't allow non-fully-parsed messages.
61
 
 
62
 
  // TODO: If unknown non-optiional (<= 0x7fff) attributes are found, send a
63
 
  //       420 "Unknown Attribute" response.
64
 
 
65
 
  // TODO: Check that a message-integrity attribute was given (or send 401
66
 
  //       "Unauthorized").  Check that a username attribute was given (or send
67
 
  //       432 "Missing Username").  Look up the username and password.  If it
68
 
  //       is missing or the HMAC is wrong, send 431 "Integrity Check Failure".
69
 
 
70
 
  // Send the message to the appropriate handler function.
71
 
  switch (msg.type()) {
72
 
  case STUN_BINDING_REQUEST:
73
 
    OnBindingRequest(&msg, remote_addr);
74
 
    return;
75
 
 
76
 
  case STUN_ALLOCATE_REQUEST:
77
 
    OnAllocateRequest(&msg, remote_addr);
78
 
    return;
79
 
 
80
 
  default:
81
 
    SendErrorResponse(msg, remote_addr, 600, "Operation Not Supported");
82
 
  }
83
 
}
84
 
 
85
 
void StunServer::OnBindingRequest(
86
 
    StunMessage* msg, const talk_base::SocketAddress& remote_addr) {
87
 
  StunMessage response;
88
 
  response.SetType(STUN_BINDING_RESPONSE);
89
 
  response.SetTransactionID(msg->transaction_id());
90
 
 
91
 
  // Tell the user the address that we received their request from.
92
 
  StunAddressAttribute* mapped_addr;
93
 
  if (!msg->IsLegacy()) {
94
 
    mapped_addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
95
 
  } else {
96
 
    mapped_addr = StunAttribute::CreateAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
97
 
  }
98
 
  mapped_addr->SetPort(remote_addr.port());
99
 
  mapped_addr->SetIP(remote_addr.ipaddr());
100
 
  response.AddAttribute(mapped_addr);
101
 
 
102
 
  // TODO: Add username and message-integrity.
103
 
 
104
 
  SendResponse(response, remote_addr);
105
 
}
106
 
 
107
 
void StunServer::OnAllocateRequest(
108
 
    StunMessage* msg, const talk_base::SocketAddress& addr) {
109
 
  SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
110
 
}
111
 
 
112
 
void StunServer::OnSharedSecretRequest(
113
 
    StunMessage* msg, const talk_base::SocketAddress& addr) {
114
 
  SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
115
 
}
116
 
 
117
 
void StunServer::OnSendRequest(StunMessage* msg,
118
 
                               const talk_base::SocketAddress& addr) {
119
 
  SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
120
 
}
121
 
 
122
 
void StunServer::SendErrorResponse(
123
 
    const StunMessage& msg, const talk_base::SocketAddress& addr,
124
 
    int error_code, const char* error_desc) {
125
 
 
126
 
  StunMessage err_msg;
127
 
  err_msg.SetType(GetStunErrorResponseType(msg.type()));
128
 
  err_msg.SetTransactionID(msg.transaction_id());
129
 
 
130
 
  StunErrorCodeAttribute* err_code = StunAttribute::CreateErrorCode();
131
 
  err_code->SetErrorClass(error_code / 100);
132
 
  err_code->SetNumber(error_code % 100);
133
 
  err_code->SetReason(error_desc);
134
 
  err_msg.AddAttribute(err_code);
135
 
 
136
 
  SendResponse(err_msg, addr);
137
 
}
138
 
 
139
 
void StunServer::SendResponse(
140
 
    const StunMessage& msg, const talk_base::SocketAddress& addr) {
141
 
 
142
 
  talk_base::ByteBuffer buf;
143
 
  msg.Write(&buf);
144
 
 
145
 
  // TODO: Allow response addr attribute if sent from another stun server.
146
 
 
147
 
  if (socket_->SendTo(buf.Data(), buf.Length(), addr) < 0)
148
 
    LOG_ERR(LS_ERROR) << "sendto";
149
 
}
150
 
 
151
 
}  // namespace cricket