1/*
2 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_BASE_WIN32SOCKETSERVER_H_
12#define WEBRTC_BASE_WIN32SOCKETSERVER_H_
13
14#if defined(WEBRTC_WIN)
15#include "webrtc/base/asyncsocket.h"
16#include "webrtc/base/criticalsection.h"
17#include "webrtc/base/messagequeue.h"
18#include "webrtc/base/socketserver.h"
19#include "webrtc/base/socketfactory.h"
20#include "webrtc/base/socket.h"
21#include "webrtc/base/thread.h"
22#include "webrtc/base/win32window.h"
23
24namespace rtc {
25
26///////////////////////////////////////////////////////////////////////////////
27// Win32Socket
28///////////////////////////////////////////////////////////////////////////////
29
30class Win32Socket : public AsyncSocket {
31 public:
32  Win32Socket();
33  virtual ~Win32Socket();
34
35  bool CreateT(int family, int type);
36
37  int Attach(SOCKET s);
38  void SetTimeout(int ms);
39
40  // AsyncSocket Interface
41  virtual SocketAddress GetLocalAddress() const;
42  virtual SocketAddress GetRemoteAddress() const;
43  virtual int Bind(const SocketAddress& addr);
44  virtual int Connect(const SocketAddress& addr);
45  virtual int Send(const void *buffer, size_t length);
46  virtual int SendTo(const void *buffer, size_t length, const SocketAddress& addr);
47  virtual int Recv(void *buffer, size_t length);
48  virtual int RecvFrom(void *buffer, size_t length, SocketAddress *out_addr);
49  virtual int Listen(int backlog);
50  virtual Win32Socket *Accept(SocketAddress *out_addr);
51  virtual int Close();
52  virtual int GetError() const;
53  virtual void SetError(int error);
54  virtual ConnState GetState() const;
55  virtual int EstimateMTU(uint16_t* mtu);
56  virtual int GetOption(Option opt, int* value);
57  virtual int SetOption(Option opt, int value);
58
59 private:
60  void CreateSink();
61  bool SetAsync(int events);
62  int DoConnect(const SocketAddress& addr);
63  bool HandleClosed(int close_error);
64  void PostClosed();
65  void UpdateLastError();
66  static int TranslateOption(Option opt, int* slevel, int* sopt);
67
68  void OnSocketNotify(SOCKET socket, int event, int error);
69  void OnDnsNotify(HANDLE task, int error);
70
71  SOCKET socket_;
72  int error_;
73  ConnState state_;
74  SocketAddress addr_;         // address that we connected to (see DoConnect)
75  uint32_t connect_time_;
76  bool closing_;
77  int close_error_;
78
79  class EventSink;
80  friend class EventSink;
81  EventSink * sink_;
82
83  struct DnsLookup;
84  DnsLookup * dns_;
85};
86
87///////////////////////////////////////////////////////////////////////////////
88// Win32SocketServer
89///////////////////////////////////////////////////////////////////////////////
90
91class Win32SocketServer : public SocketServer {
92 public:
93  explicit Win32SocketServer(MessageQueue* message_queue);
94  virtual ~Win32SocketServer();
95
96  void set_modeless_dialog(HWND hdlg) {
97    hdlg_ = hdlg;
98  }
99
100  // SocketServer Interface
101  virtual Socket* CreateSocket(int type);
102  virtual Socket* CreateSocket(int family, int type);
103
104  virtual AsyncSocket* CreateAsyncSocket(int type);
105  virtual AsyncSocket* CreateAsyncSocket(int family, int type);
106
107  virtual void SetMessageQueue(MessageQueue* queue);
108  virtual bool Wait(int cms, bool process_io);
109  virtual void WakeUp();
110
111  void Pump();
112
113  HWND handle() { return wnd_.handle(); }
114
115 private:
116  class MessageWindow : public Win32Window {
117   public:
118    explicit MessageWindow(Win32SocketServer* ss) : ss_(ss) {}
119   private:
120    virtual bool OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT& result);
121    Win32SocketServer* ss_;
122  };
123
124  static const TCHAR kWindowName[];
125  MessageQueue *message_queue_;
126  MessageWindow wnd_;
127  CriticalSection cs_;
128  bool posted_;
129  HWND hdlg_;
130};
131
132///////////////////////////////////////////////////////////////////////////////
133// Win32Thread. Automatically pumps Windows messages.
134///////////////////////////////////////////////////////////////////////////////
135
136class Win32Thread : public Thread {
137 public:
138  Win32Thread() : ss_(this), id_(0) {
139    set_socketserver(&ss_);
140  }
141  virtual ~Win32Thread() {
142    Stop();
143    set_socketserver(NULL);
144  }
145  virtual void Run() {
146    id_ = GetCurrentThreadId();
147    Thread::Run();
148    id_ = 0;
149  }
150  virtual void Quit() {
151    PostThreadMessage(id_, WM_QUIT, 0, 0);
152  }
153 private:
154  Win32SocketServer ss_;
155  DWORD id_;
156};
157
158///////////////////////////////////////////////////////////////////////////////
159
160}  // namespace rtc
161
162#endif  // WEBRTC_WIN
163
164#endif  // WEBRTC_BASE_WIN32SOCKETSERVER_H_
165