copy wangle back into folly
[folly.git] / folly / wangle / bootstrap / ServerSocketFactory.h
1 /*
2  * Copyright 2015 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17
18 #include <folly/wangle/bootstrap/ServerBootstrap-inl.h>
19 #include <folly/io/async/AsyncServerSocket.h>
20 #include <folly/io/async/EventBaseManager.h>
21 #include <folly/io/async/AsyncUDPServerSocket.h>
22
23 namespace folly {
24
25 class ServerSocketFactory {
26  public:
27   virtual std::shared_ptr<AsyncSocketBase> newSocket(
28     int port, SocketAddress address, int backlog,
29     bool reuse, ServerSocketConfig& config) = 0;
30
31   virtual void stopSocket(
32     std::shared_ptr<AsyncSocketBase>& socket) = 0;
33
34   virtual void removeAcceptCB(std::shared_ptr<AsyncSocketBase> sock, Acceptor *callback, EventBase* base) = 0;
35   virtual void addAcceptCB(std::shared_ptr<AsyncSocketBase> sock, Acceptor* callback, EventBase* base) = 0 ;
36   virtual ~ServerSocketFactory() = default;
37 };
38
39 class AsyncServerSocketFactory : public ServerSocketFactory {
40  public:
41   std::shared_ptr<AsyncSocketBase> newSocket(
42       int port, SocketAddress address, int backlog, bool reuse,
43       ServerSocketConfig& config) {
44
45     auto socket = folly::AsyncServerSocket::newSocket();
46     socket->setReusePortEnabled(reuse);
47     socket->attachEventBase(EventBaseManager::get()->getEventBase());
48     if (port >= 0) {
49       socket->bind(port);
50     } else {
51       socket->bind(address);
52     }
53
54     socket->listen(config.acceptBacklog);
55     socket->startAccepting();
56
57     return socket;
58   }
59
60   virtual void stopSocket(
61     std::shared_ptr<AsyncSocketBase>& s) {
62     auto socket = std::dynamic_pointer_cast<AsyncServerSocket>(s);
63     DCHECK(socket);
64     socket->stopAccepting();
65     socket->detachEventBase();
66   }
67
68   virtual void removeAcceptCB(std::shared_ptr<AsyncSocketBase> s,
69                               Acceptor *callback, EventBase* base) {
70     auto socket = std::dynamic_pointer_cast<AsyncServerSocket>(s);
71     CHECK(socket);
72     socket->removeAcceptCallback(callback, base);
73   }
74
75   virtual void addAcceptCB(std::shared_ptr<AsyncSocketBase> s,
76                                  Acceptor* callback, EventBase* base) {
77     auto socket = std::dynamic_pointer_cast<AsyncServerSocket>(s);
78     CHECK(socket);
79     socket->addAcceptCallback(callback, base);
80   }
81 };
82
83 class AsyncUDPServerSocketFactory : public ServerSocketFactory {
84  public:
85   std::shared_ptr<AsyncSocketBase> newSocket(
86       int port, SocketAddress address, int backlog, bool reuse,
87       ServerSocketConfig& config) {
88
89     auto socket = std::make_shared<AsyncUDPServerSocket>(
90       EventBaseManager::get()->getEventBase());
91     socket->setReusePort(reuse);
92     if (port >= 0) {
93       SocketAddress addressr("::1", port);
94       socket->bind(addressr);
95     } else {
96       socket->bind(address);
97     }
98     socket->listen();
99
100     return socket;
101   }
102
103   virtual void stopSocket(
104     std::shared_ptr<AsyncSocketBase>& s) {
105     auto socket = std::dynamic_pointer_cast<AsyncUDPServerSocket>(s);
106     DCHECK(socket);
107     socket->close();
108   }
109
110   virtual void removeAcceptCB(std::shared_ptr<AsyncSocketBase> s,
111                               Acceptor *callback, EventBase* base) {
112   }
113
114   virtual void addAcceptCB(std::shared_ptr<AsyncSocketBase> s,
115                                  Acceptor* callback, EventBase* base) {
116     auto socket = std::dynamic_pointer_cast<AsyncUDPServerSocket>(s);
117     DCHECK(socket);
118     socket->addListener(base, callback);
119   }
120 };
121
122 } // namespace