a932f4e4d1ad43f9a98a6685cf814ac42c969721
[folly.git] / folly / io / async / AsyncServerSocket.h
1 /*
2  * Copyright 2014 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
17 #pragma once
18
19 #include <folly/io/async/DelayedDestruction.h>
20 #include <folly/io/async/EventHandler.h>
21 #include <folly/io/async/EventBase.h>
22 #include <folly/io/async/NotificationQueue.h>
23 #include <folly/io/async/AsyncTimeout.h>
24 #include <folly/io/ShutdownSocketSet.h>
25 #include <folly/SocketAddress.h>
26 #include <memory>
27 #include <exception>
28 #include <vector>
29 #include <limits.h>
30 #include <stddef.h>
31 #include <sys/socket.h>
32
33
34 // Due to the way kernel headers are included, this may or may not be defined.
35 // Number pulled from 3.10 kernel headers.
36 #ifndef SO_REUSEPORT
37 #define SO_REUSEPORT 15
38 #endif
39
40 namespace folly {
41
42 /**
43  * A listening socket that asynchronously informs a callback whenever a new
44  * connection has been accepted.
45  *
46  * Unlike most async interfaces that always invoke their callback in the same
47  * EventBase thread, AsyncServerSocket is unusual in that it can distribute
48  * the callbacks across multiple EventBase threads.
49  *
50  * This supports a common use case for network servers to distribute incoming
51  * connections across a number of EventBase threads.  (Servers typically run
52  * with one EventBase thread per CPU.)
53  *
54  * Despite being able to invoke callbacks in multiple EventBase threads,
55  * AsyncServerSocket still has one "primary" EventBase.  Operations that
56  * modify the AsyncServerSocket state may only be performed from the primary
57  * EventBase thread.
58  */
59 class AsyncServerSocket : public DelayedDestruction {
60  public:
61   typedef std::unique_ptr<AsyncServerSocket, Destructor> UniquePtr;
62
63   class AcceptCallback {
64    public:
65     virtual ~AcceptCallback() {}
66
67     /**
68      * connectionAccepted() is called whenever a new client connection is
69      * received.
70      *
71      * The AcceptCallback will remain installed after connectionAccepted()
72      * returns.
73      *
74      * @param fd          The newly accepted client socket.  The AcceptCallback
75      *                    assumes ownership of this socket, and is responsible
76      *                    for closing it when done.  The newly accepted file
77      *                    descriptor will have already been put into
78      *                    non-blocking mode.
79      * @param clientAddr  A reference to a TSocketAddress struct containing the
80      *                    client's address.  This struct is only guaranteed to
81      *                    remain valid until connectionAccepted() returns.
82      */
83     virtual void connectionAccepted(int fd,
84                                     const SocketAddress& clientAddr)
85       noexcept = 0;
86
87     /**
88      * acceptError() is called if an error occurs while accepting.
89      *
90      * The AcceptCallback will remain installed even after an accept error,
91      * as the errors are typically somewhat transient, such as being out of
92      * file descriptors.  The server socket must be explicitly stopped if you
93      * wish to stop accepting after an error.
94      *
95      * @param ex  An exception representing the error.
96      */
97     virtual void acceptError(const std::exception& ex) noexcept = 0;
98
99     /**
100      * acceptStarted() will be called in the callback's EventBase thread
101      * after this callback has been added to the AsyncServerSocket.
102      *
103      * acceptStarted() will be called before any calls to connectionAccepted()
104      * or acceptError() are made on this callback.
105      *
106      * acceptStarted() makes it easier for callbacks to perform initialization
107      * inside the callback thread.  (The call to addAcceptCallback() must
108      * always be made from the AsyncServerSocket's primary EventBase thread.
109      * acceptStarted() provides a hook that will always be invoked in the
110      * callback's thread.)
111      *
112      * Note that the call to acceptStarted() is made once the callback is
113      * added, regardless of whether or not the AsyncServerSocket is actually
114      * accepting at the moment.  acceptStarted() will be called even if the
115      * AsyncServerSocket is paused when the callback is added (including if
116      * the initial call to startAccepting() on the AsyncServerSocket has not
117      * been made yet).
118      */
119     virtual void acceptStarted() noexcept {}
120
121     /**
122      * acceptStopped() will be called when this AcceptCallback is removed from
123      * the AsyncServerSocket, or when the AsyncServerSocket is destroyed,
124      * whichever occurs first.
125      *
126      * No more calls to connectionAccepted() or acceptError() will be made
127      * after acceptStopped() is invoked.
128      */
129     virtual void acceptStopped() noexcept {}
130   };
131
132   static const uint32_t kDefaultMaxAcceptAtOnce = 30;
133   static const uint32_t kDefaultCallbackAcceptAtOnce = 5;
134   static const uint32_t kDefaultMaxMessagesInQueue = 0;
135   /**
136    * Create a new AsyncServerSocket with the specified EventBase.
137    *
138    * @param eventBase  The EventBase to use for driving the asynchronous I/O.
139    *                   If this parameter is nullptr, attachEventBase() must be
140    *                   called before this socket can begin accepting
141    *                   connections.
142    */
143   explicit AsyncServerSocket(EventBase* eventBase = nullptr);
144
145   /**
146    * Helper function to create a shared_ptr<AsyncServerSocket>.
147    *
148    * This passes in the correct destructor object, since AsyncServerSocket's
149    * destructor is protected and cannot be invoked directly.
150    */
151   static std::shared_ptr<AsyncServerSocket>
152   newSocket(EventBase* evb = nullptr) {
153     return std::shared_ptr<AsyncServerSocket>(new AsyncServerSocket(evb),
154                                                  Destructor());
155   }
156
157   void setShutdownSocketSet(ShutdownSocketSet* newSS);
158
159   /**
160    * Destroy the socket.
161    *
162    * AsyncServerSocket::destroy() must be called to destroy the socket.
163    * The normal destructor is private, and should not be invoked directly.
164    * This prevents callers from deleting a AsyncServerSocket while it is
165    * invoking a callback.
166    *
167    * destroy() must be invoked from the socket's primary EventBase thread.
168    *
169    * If there are AcceptCallbacks still installed when destroy() is called,
170    * acceptStopped() will be called on these callbacks to notify them that
171    * accepting has stopped.  Accept callbacks being driven by other EventBase
172    * threads may continue to receive new accept callbacks for a brief period of
173    * time after destroy() returns.  They will not receive any more callback
174    * invocations once acceptStopped() is invoked.
175    */
176   virtual void destroy();
177
178   /**
179    * Attach this AsyncServerSocket to its primary EventBase.
180    *
181    * This may only be called if the AsyncServerSocket is not already attached
182    * to a EventBase.  The AsyncServerSocket must be attached to a EventBase
183    * before it can begin accepting connections.
184    */
185   void attachEventBase(EventBase *eventBase);
186
187   /**
188    * Detach the AsyncServerSocket from its primary EventBase.
189    *
190    * detachEventBase() may only be called if the AsyncServerSocket is not
191    * currently accepting connections.
192    */
193   void detachEventBase();
194
195   /**
196    * Get the EventBase used by this socket.
197    */
198   EventBase* getEventBase() const {
199     return eventBase_;
200   }
201
202   /**
203    * Create a AsyncServerSocket from an existing socket file descriptor.
204    *
205    * useExistingSocket() will cause the AsyncServerSocket to take ownership of
206    * the specified file descriptor, and use it to listen for new connections.
207    * The AsyncServerSocket will close the file descriptor when it is
208    * destroyed.
209    *
210    * useExistingSocket() must be called before bind() or listen().
211    *
212    * The supplied file descriptor will automatically be put into non-blocking
213    * mode.  The caller may have already directly called bind() and possibly
214    * listen on the file descriptor.  If so the caller should skip calling the
215    * corresponding AsyncServerSocket::bind() and listen() methods.
216    *
217    * On error a TTransportException will be thrown and the caller will retain
218    * ownership of the file descriptor.
219    */
220   void useExistingSocket(int fd);
221   void useExistingSockets(const std::vector<int>& fds);
222
223   /**
224    * Return the underlying file descriptor
225    */
226   std::vector<int> getSockets() const {
227     std::vector<int> sockets;
228     for (auto& handler : sockets_) {
229       sockets.push_back(handler.socket_);
230     }
231     return sockets;
232   }
233
234   /**
235    * Backwards compatible getSocket, warns if > 1 socket
236    */
237   int getSocket() const {
238     if (sockets_.size() > 1) {
239       VLOG(2) << "Warning: getSocket can return multiple fds, " <<
240         "but getSockets was not called, so only returning the first";
241     }
242     if (sockets_.size() == 0) {
243       return -1;
244     } else {
245       return sockets_[0].socket_;
246     }
247   }
248
249   /**
250    * Bind to the specified address.
251    *
252    * This must be called from the primary EventBase thread.
253    *
254    * Throws TTransportException on error.
255    */
256   virtual void bind(const SocketAddress& address);
257
258   /**
259    * Bind to the specified port for the specified addresses.
260    *
261    * This must be called from the primary EventBase thread.
262    *
263    * Throws TTransportException on error.
264    */
265   virtual void bind(
266       const std::vector<IPAddress>& ipAddresses,
267       uint16_t port);
268
269   /**
270    * Bind to the specified port.
271    *
272    * This must be called from the primary EventBase thread.
273    *
274    * Throws TTransportException on error.
275    */
276   virtual void bind(uint16_t port);
277
278   /**
279    * Get the local address to which the socket is bound.
280    *
281    * Throws TTransportException on error.
282    */
283   void getAddress(SocketAddress* addressReturn) const;
284
285   /**
286    * Get all the local addresses to which the socket is bound.
287    *
288    * Throws TTransportException on error.
289    */
290   std::vector<SocketAddress> getAddresses() const;
291
292   /**
293    * Begin listening for connections.
294    *
295    * This calls ::listen() with the specified backlog.
296    *
297    * Once listen() is invoked the socket will actually be open so that remote
298    * clients may establish connections.  (Clients that attempt to connect
299    * before listen() is called will receive a connection refused error.)
300    *
301    * At least one callback must be set and startAccepting() must be called to
302    * actually begin notifying the accept callbacks of newly accepted
303    * connections.  The backlog parameter controls how many connections the
304    * kernel will accept and buffer internally while the accept callbacks are
305    * paused (or if accepting is enabled but the callbacks cannot keep up).
306    *
307    * bind() must be called before calling listen().
308    * listen() must be called from the primary EventBase thread.
309    *
310    * Throws TTransportException on error.
311    */
312   virtual void listen(int backlog);
313
314   /**
315    * Add an AcceptCallback.
316    *
317    * When a new socket is accepted, one of the AcceptCallbacks will be invoked
318    * with the new socket.  The AcceptCallbacks are invoked in a round-robin
319    * fashion.  This allows the accepted sockets to distributed among a pool of
320    * threads, each running its own EventBase object.  This is a common model,
321    * since most asynchronous-style servers typically run one EventBase thread
322    * per CPU.
323    *
324    * The EventBase object associated with each AcceptCallback must be running
325    * its loop.  If the EventBase loop is not running, sockets will still be
326    * scheduled for the callback, but the callback cannot actually get invoked
327    * until the loop runs.
328    *
329    * This method must be invoked from the AsyncServerSocket's primary
330    * EventBase thread.
331    *
332    * Note that startAccepting() must be called on the AsyncServerSocket to
333    * cause it to actually start accepting sockets once callbacks have been
334    * installed.
335    *
336    * @param callback   The callback to invoke.
337    * @param eventBase  The EventBase to use to invoke the callback.  This
338    *     parameter may be nullptr, in which case the callback will be invoked in
339    *     the AsyncServerSocket's primary EventBase.
340    * @param maxAtOnce  The maximum number of connections to accept in this
341    *                   callback on a single iteration of the event base loop.
342    *                   This only takes effect when eventBase is non-nullptr.
343    *                   When using a nullptr eventBase for the callback, the
344    *                   setMaxAcceptAtOnce() method controls how many
345    *                   connections the main event base will accept at once.
346    */
347   virtual void addAcceptCallback(
348     AcceptCallback *callback,
349     EventBase *eventBase,
350     uint32_t maxAtOnce = kDefaultCallbackAcceptAtOnce);
351
352   /**
353    * Remove an AcceptCallback.
354    *
355    * This allows a single AcceptCallback to be removed from the round-robin
356    * pool.
357    *
358    * This method must be invoked from the AsyncServerSocket's primary
359    * EventBase thread.  Use EventBase::runInEventBaseThread() to schedule the
360    * operation in the correct EventBase if your code is not in the server
361    * socket's primary EventBase.
362    *
363    * Given that the accept callback is being driven by a different EventBase,
364    * the AcceptCallback may continue to be invoked for a short period of time
365    * after removeAcceptCallback() returns in this thread.  Once the other
366    * EventBase thread receives the notification to stop, it will call
367    * acceptStopped() on the callback to inform it that it is fully stopped and
368    * will not receive any new sockets.
369    *
370    * If the last accept callback is removed while the socket is accepting,
371    * the socket will implicitly pause accepting.  If a callback is later added,
372    * it will resume accepting immediately, without requiring startAccepting()
373    * to be invoked.
374    *
375    * @param callback   The callback to uninstall.
376    * @param eventBase  The EventBase associated with this callback.  This must
377    *     be the same EventBase that was used when the callback was installed
378    *     with addAcceptCallback().
379    */
380   void removeAcceptCallback(AcceptCallback *callback, EventBase *eventBase);
381
382   /**
383    * Begin accepting connctions on this socket.
384    *
385    * bind() and listen() must be called before calling startAccepting().
386    *
387    * When a AsyncServerSocket is initially created, it will not begin
388    * accepting connections until at least one callback has been added and
389    * startAccepting() has been called.  startAccepting() can also be used to
390    * resume accepting connections after a call to pauseAccepting().
391    *
392    * If startAccepting() is called when there are no accept callbacks
393    * installed, the socket will not actually begin accepting until an accept
394    * callback is added.
395    *
396    * This method may only be called from the primary EventBase thread.
397    */
398   virtual void startAccepting();
399
400   /**
401    * Pause accepting connections.
402    *
403    * startAccepting() may be called to resume accepting.
404    *
405    * This method may only be called from the primary EventBase thread.
406    * If there are AcceptCallbacks being driven by other EventBase threads they
407    * may continue to receive callbacks for a short period of time after
408    * pauseAccepting() returns.
409    *
410    * Unlike removeAcceptCallback() or destroy(), acceptStopped() will not be
411    * called on the AcceptCallback objects simply due to a temporary pause.  If
412    * the server socket is later destroyed while paused, acceptStopped() will be
413    * called all of the installed AcceptCallbacks.
414    */
415   void pauseAccepting();
416
417   /**
418    * Shutdown the listen socket and notify all callbacks that accept has
419    * stopped, but don't close the socket.  This invokes shutdown(2) with the
420    * supplied argument.  Passing -1 will close the socket now.  Otherwise, the
421    * close will be delayed until this object is destroyed.
422    *
423    * Only use this if you have reason to pass special flags to shutdown.
424    * Otherwise just destroy the socket.
425    *
426    * This method has no effect when a ShutdownSocketSet option is used.
427    *
428    * Returns the result of shutdown on sockets_[n-1]
429    */
430   int stopAccepting(int shutdownFlags = -1);
431
432   /**
433    * Get the maximum number of connections that will be accepted each time
434    * around the event loop.
435    */
436   uint32_t getMaxAcceptAtOnce() const {
437     return maxAcceptAtOnce_;
438   }
439
440   /**
441    * Set the maximum number of connections that will be accepted each time
442    * around the event loop.
443    *
444    * This provides a very coarse-grained way of controlling how fast the
445    * AsyncServerSocket will accept connections.  If you find that when your
446    * server is overloaded AsyncServerSocket accepts connections more quickly
447    * than your code can process them, you can try lowering this number so that
448    * fewer connections will be accepted each event loop iteration.
449    *
450    * For more explicit control over the accept rate, you can also use
451    * pauseAccepting() to temporarily pause accepting when your server is
452    * overloaded, and then use startAccepting() later to resume accepting.
453    */
454   void setMaxAcceptAtOnce(uint32_t numConns) {
455     maxAcceptAtOnce_ = numConns;
456   }
457
458   /**
459    * Get the maximum number of unprocessed messages which a NotificationQueue
460    * can hold.
461    */
462   uint32_t getMaxNumMessagesInQueue() const {
463     return maxNumMsgsInQueue_;
464   }
465
466   /**
467    * Set the maximum number of unprocessed messages in NotificationQueue.
468    * No new message will be sent to that NotificationQueue if there are more
469    * than such number of unprocessed messages in that queue.
470    *
471    * Only works if called before addAcceptCallback.
472    */
473   void setMaxNumMessagesInQueue(uint32_t num) {
474     maxNumMsgsInQueue_ = num;
475   }
476
477   /**
478    * Get the speed of adjusting connection accept rate.
479    */
480   double getAcceptRateAdjustSpeed() const {
481     return acceptRateAdjustSpeed_;
482   }
483
484   /**
485    * Set the speed of adjusting connection accept rate.
486    */
487   void setAcceptRateAdjustSpeed(double speed) {
488     acceptRateAdjustSpeed_ = speed;
489   }
490
491   /**
492    * Get the number of connections dropped by the AsyncServerSocket
493    */
494   uint64_t getNumDroppedConnections() const {
495     return numDroppedConnections_;
496   }
497
498   /**
499    * Set whether or not SO_KEEPALIVE should be enabled on the server socket
500    * (and thus on all subsequently-accepted connections). By default, keepalive
501    * is enabled.
502    *
503    * Note that TCP keepalive usually only kicks in after the connection has
504    * been idle for several hours. Applications should almost always have their
505    * own, shorter idle timeout.
506    */
507   void setKeepAliveEnabled(bool enabled) {
508     keepAliveEnabled_ = enabled;
509
510     for (auto& handler : sockets_) {
511       if (handler.socket_ < 0) {
512         continue;
513       }
514
515       int val = (enabled) ? 1 : 0;
516       if (setsockopt(handler.socket_, SOL_SOCKET,
517                      SO_KEEPALIVE, &val, sizeof(val)) != 0) {
518         LOG(ERROR) << "failed to set SO_KEEPALIVE on async server socket: %s" <<
519                 strerror(errno);
520       }
521     }
522   }
523
524   /**
525    * Get whether or not SO_KEEPALIVE is enabled on the server socket.
526    */
527   bool getKeepAliveEnabled() const {
528     return keepAliveEnabled_;
529   }
530
531   /**
532    * Set whether or not SO_REUSEPORT should be enabled on the server socket,
533    * allowing multiple binds to the same port
534    */
535   void setReusePortEnabled(bool enabled) {
536     reusePortEnabled_ = enabled;
537
538     for (auto& handler : sockets_) {
539       if (handler.socket_ < 0) {
540         continue;
541       }
542
543       int val = (enabled) ? 1 : 0;
544       if (setsockopt(handler.socket_, SOL_SOCKET,
545                      SO_REUSEPORT, &val, sizeof(val)) != 0) {
546         LOG(ERROR) <<
547           "failed to set SO_REUSEPORT on async server socket " << errno;
548         folly::throwSystemError(errno,
549                                 "failed to bind to async server socket");
550       }
551     }
552   }
553
554   /**
555    * Get whether or not SO_REUSEPORT is enabled on the server socket.
556    */
557   bool getReusePortEnabled_() const {
558     return reusePortEnabled_;
559   }
560
561   /**
562    * Set whether or not the socket should close during exec() (FD_CLOEXEC). By
563    * default, this is enabled
564    */
565   void setCloseOnExec(bool closeOnExec) {
566     closeOnExec_ = closeOnExec;
567   }
568
569   /**
570    * Get whether or not FD_CLOEXEC is enabled on the server socket.
571    */
572   bool getCloseOnExec() const {
573     return closeOnExec_;
574   }
575
576  protected:
577   /**
578    * Protected destructor.
579    *
580    * Invoke destroy() instead to destroy the AsyncServerSocket.
581    */
582   virtual ~AsyncServerSocket();
583
584  private:
585   enum class MessageType {
586     MSG_NEW_CONN = 0,
587     MSG_ERROR = 1
588   };
589
590   struct QueueMessage {
591     MessageType type;
592     int fd;
593     int err;
594     SocketAddress address;
595     std::string msg;
596   };
597
598   /**
599    * A class to receive notifications to invoke AcceptCallback objects
600    * in other EventBase threads.
601    *
602    * A RemoteAcceptor object is created for each AcceptCallback that
603    * is installed in a separate EventBase thread.  The RemoteAcceptor
604    * receives notification of new sockets via a NotificationQueue,
605    * and then invokes the AcceptCallback.
606    */
607   class RemoteAcceptor
608       : private NotificationQueue<QueueMessage>::Consumer {
609   public:
610     explicit RemoteAcceptor(AcceptCallback *callback)
611       : callback_(callback) {}
612
613     ~RemoteAcceptor() {}
614
615     void start(EventBase *eventBase, uint32_t maxAtOnce, uint32_t maxInQueue);
616     void stop(EventBase* eventBase, AcceptCallback* callback);
617
618     virtual void messageAvailable(QueueMessage&& message);
619
620     NotificationQueue<QueueMessage>* getQueue() {
621       return &queue_;
622     }
623
624   private:
625     AcceptCallback *callback_;
626
627     NotificationQueue<QueueMessage> queue_;
628   };
629
630   /**
631    * A struct to keep track of the callbacks associated with this server
632    * socket.
633    */
634   struct CallbackInfo {
635     CallbackInfo(AcceptCallback *cb, EventBase *evb)
636       : callback(cb),
637         eventBase(evb),
638         consumer(nullptr) {}
639
640     AcceptCallback *callback;
641     EventBase *eventBase;
642
643     RemoteAcceptor* consumer;
644   };
645
646   class BackoffTimeout;
647
648   virtual void handlerReady(
649     uint16_t events, int socket, sa_family_t family) noexcept;
650
651   int createSocket(int family);
652   void setupSocket(int fd);
653   void bindSocket(int fd, const SocketAddress& address, bool isExistingSocket);
654   void dispatchSocket(int socket, SocketAddress&& address);
655   void dispatchError(const char *msg, int errnoValue);
656   void enterBackoff();
657   void backoffTimeoutExpired();
658
659   CallbackInfo* nextCallback() {
660     CallbackInfo* info = &callbacks_[callbackIndex_];
661
662     ++callbackIndex_;
663     if (callbackIndex_ >= callbacks_.size()) {
664       callbackIndex_ = 0;
665     }
666
667     return info;
668   }
669
670   struct ServerEventHandler : public EventHandler {
671     ServerEventHandler(EventBase* eventBase, int socket,
672                        AsyncServerSocket* parent,
673                       sa_family_t addressFamily)
674         : EventHandler(eventBase, socket)
675         , eventBase_(eventBase)
676         , socket_(socket)
677         , parent_(parent)
678         , addressFamily_(addressFamily) {}
679
680     ServerEventHandler(const ServerEventHandler& other)
681     : EventHandler(other.eventBase_, other.socket_)
682     , eventBase_(other.eventBase_)
683     , socket_(other.socket_)
684     , parent_(other.parent_)
685     , addressFamily_(other.addressFamily_) {}
686
687     ServerEventHandler& operator=(
688         const ServerEventHandler& other) {
689       if (this != &other) {
690         eventBase_ = other.eventBase_;
691         socket_ = other.socket_;
692         parent_ = other.parent_;
693         addressFamily_ = other.addressFamily_;
694
695         detachEventBase();
696         attachEventBase(other.eventBase_);
697         changeHandlerFD(other.socket_);
698       }
699       return *this;
700     }
701
702     // Inherited from EventHandler
703     virtual void handlerReady(uint16_t events) noexcept {
704       parent_->handlerReady(events, socket_, addressFamily_);
705     }
706
707     EventBase* eventBase_;
708     int socket_;
709     AsyncServerSocket* parent_;
710     sa_family_t addressFamily_;
711   };
712
713   EventBase *eventBase_;
714   std::vector<ServerEventHandler> sockets_;
715   std::vector<int> pendingCloseSockets_;
716   bool accepting_;
717   uint32_t maxAcceptAtOnce_;
718   uint32_t maxNumMsgsInQueue_;
719   double acceptRateAdjustSpeed_;  //0 to disable auto adjust
720   double acceptRate_;
721   std::chrono::time_point<std::chrono::steady_clock> lastAccepTimestamp_;
722   uint64_t numDroppedConnections_;
723   uint32_t callbackIndex_;
724   BackoffTimeout *backoffTimeout_;
725   std::vector<CallbackInfo> callbacks_;
726   bool keepAliveEnabled_;
727   bool reusePortEnabled_{false};
728   bool closeOnExec_;
729   ShutdownSocketSet* shutdownSocketSet_;
730 };
731
732 } // folly