1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/*
2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *
4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */
10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifndef WEBRTC_BASE_TESTECHOSERVER_H_
12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define WEBRTC_BASE_TESTECHOSERVER_H_
13f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <list>
15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/asynctcpsocket.h"
16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/socketaddress.h"
17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/sigslot.h"
18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/thread.h"
19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc {
21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// A test echo server, echoes back any packets sent to it.
23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Useful for unit tests.
24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass TestEchoServer : public sigslot::has_slots<> {
25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TestEchoServer(Thread* thread, const SocketAddress& addr)
27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      : server_socket_(thread->socketserver()->CreateAsyncSocket(addr.family(),
28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                                 SOCK_STREAM)) {
29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    server_socket_->Bind(addr);
30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    server_socket_->Listen(5);
31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    server_socket_->SignalReadEvent.connect(this, &TestEchoServer::OnAccept);
32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ~TestEchoServer() {
34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    for (ClientList::iterator it = client_sockets_.begin();
35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org         it != client_sockets_.end(); ++it) {
36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      delete *it;
37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress address() const { return server_socket_->GetLocalAddress(); }
41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnAccept(AsyncSocket* socket) {
44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    AsyncSocket* raw_socket = socket->Accept(NULL);
45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (raw_socket) {
46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      AsyncTCPSocket* packet_socket = new AsyncTCPSocket(raw_socket, false);
47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      packet_socket->SignalReadPacket.connect(this, &TestEchoServer::OnPacket);
48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      packet_socket->SignalClose.connect(this, &TestEchoServer::OnClose);
49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      client_sockets_.push_back(packet_socket);
50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size,
53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                const SocketAddress& remote_addr,
54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                const PacketTime& packet_time) {
55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    rtc::PacketOptions options;
56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    socket->Send(buf, size, options);
57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnClose(AsyncPacketSocket* socket, int err) {
59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ClientList::iterator it =
60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        std::find(client_sockets_.begin(), client_sockets_.end(), socket);
61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    client_sockets_.erase(it);
62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Thread::Current()->Dispose(socket);
63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  typedef std::list<AsyncTCPSocket*> ClientList;
66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server_socket_;
67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ClientList client_sockets_;
683c089d751ede283e21e186885eaf705c3257ccd2henrikg  RTC_DISALLOW_COPY_AND_ASSIGN(TestEchoServer);
69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}  // namespace rtc
72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif  // WEBRTC_BASE_TESTECHOSERVER_H_
74