rf-web/vendor/bundle/gems/eventmachine-1.2.7/ext/ed.h

458 lines
12 KiB
C
Raw Normal View History

2019-10-21 08:18:17 +00:00
/*****************************************************************************
$Id$
File: ed.h
Date: 06Apr06
Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
Gmail: blackhedd
This program is free software; you can redistribute it and/or modify
it under the terms of either: 1) the GNU General Public License
as published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version; or 2) Ruby's License.
See the file COPYING for complete licensing information.
*****************************************************************************/
#ifndef __EventableDescriptor__H_
#define __EventableDescriptor__H_
class EventMachine_t; // forward reference
#ifdef WITH_SSL
class SslBox_t; // forward reference
#endif
bool SetSocketNonblocking (SOCKET);
bool SetFdCloexec (int);
/*************************
class EventableDescriptor
*************************/
class EventableDescriptor: public Bindable_t
{
public:
EventableDescriptor (SOCKET, EventMachine_t*);
virtual ~EventableDescriptor() NO_EXCEPT_FALSE;
SOCKET GetSocket() {return MySocket;}
void SetSocketInvalid() { MySocket = INVALID_SOCKET; }
void Close();
virtual void Read() = 0;
virtual void Write() = 0;
virtual void Heartbeat() = 0;
// These methods tell us whether the descriptor
// should be selected or polled for read/write.
virtual bool SelectForRead() = 0;
virtual bool SelectForWrite() = 0;
// are we scheduled for a close, or in an error state, or already closed?
bool ShouldDelete();
// Do we have any data to write? This is used by ShouldDelete.
virtual int GetOutboundDataSize() {return 0;}
virtual bool IsWatchOnly(){ return bWatchOnly; }
virtual void ScheduleClose (bool after_writing);
bool IsCloseScheduled();
virtual void HandleError(){ ScheduleClose (false); }
void SetEventCallback (EMCallback);
virtual bool GetPeername (struct sockaddr*, socklen_t*) = 0;
virtual bool GetSockname (struct sockaddr*, socklen_t*) = 0;
virtual bool GetSubprocessPid (pid_t*) {return false;}
virtual void StartTls() {}
virtual void SetTlsParms (const char *, const char *, bool, bool, const char *, const char *, const char *, const char *, int) {}
#ifdef WITH_SSL
virtual X509 *GetPeerCert() {return NULL;}
virtual int GetCipherBits() {return -1;}
virtual const char *GetCipherName() {return NULL;}
virtual const char *GetCipherProtocol() {return NULL;}
virtual const char *GetSNIHostname() {return NULL;}
#endif
virtual uint64_t GetCommInactivityTimeout() {return 0;}
virtual int SetCommInactivityTimeout (uint64_t) {return 0;}
uint64_t GetPendingConnectTimeout();
int SetPendingConnectTimeout (uint64_t value);
uint64_t GetLastActivity() { return LastActivity; }
#ifdef HAVE_EPOLL
struct epoll_event *GetEpollEvent() { return &EpollEvent; }
#endif
#ifdef HAVE_KQUEUE
bool GetKqueueArmWrite() { return bKqueueArmWrite; }
#endif
virtual void StartProxy(const uintptr_t, const unsigned long, const unsigned long);
virtual void StopProxy();
virtual unsigned long GetProxiedBytes(){ return ProxiedBytes; };
virtual void SetProxiedFrom(EventableDescriptor*, const unsigned long);
virtual int SendOutboundData(const char*,unsigned long){ return -1; }
virtual bool IsPaused(){ return bPaused; }
virtual bool Pause(){ bPaused = true; return bPaused; }
virtual bool Resume(){ bPaused = false; return bPaused; }
void SetUnbindReasonCode(int code){ UnbindReasonCode = code; }
virtual int ReportErrorStatus(){ return 0; }
virtual bool IsConnectPending(){ return false; }
virtual uint64_t GetNextHeartbeat();
private:
bool bCloseNow;
bool bCloseAfterWriting;
protected:
SOCKET MySocket;
bool bAttached;
bool bWatchOnly;
EMCallback EventCallback;
void _GenericInboundDispatch (const char *buffer, unsigned long size);
bool _GenericGetPeername (struct sockaddr*, socklen_t*);
bool _GenericGetSockname (struct sockaddr*, socklen_t*);
uint64_t CreatedAt;
bool bCallbackUnbind;
int UnbindReasonCode;
unsigned long BytesToProxy;
EventableDescriptor *ProxyTarget;
EventableDescriptor *ProxiedFrom;
unsigned long ProxiedBytes;
unsigned long MaxOutboundBufSize;
#ifdef HAVE_EPOLL
struct epoll_event EpollEvent;
#endif
#ifdef HAVE_KQUEUE
bool bKqueueArmWrite;
#endif
EventMachine_t *MyEventMachine;
uint64_t PendingConnectTimeout;
uint64_t InactivityTimeout;
uint64_t LastActivity;
uint64_t NextHeartbeat;
bool bPaused;
};
/*************************
class LoopbreakDescriptor
*************************/
class LoopbreakDescriptor: public EventableDescriptor
{
public:
LoopbreakDescriptor (SOCKET, EventMachine_t*);
virtual ~LoopbreakDescriptor() {}
virtual void Read();
virtual void Write();
virtual void Heartbeat() {}
virtual bool SelectForRead() {return true;}
virtual bool SelectForWrite() {return false;}
virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); }
virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); }
};
/**************************
class ConnectionDescriptor
**************************/
class ConnectionDescriptor: public EventableDescriptor
{
public:
ConnectionDescriptor (SOCKET, EventMachine_t*);
virtual ~ConnectionDescriptor();
int SendOutboundData (const char*, unsigned long);
void SetConnectPending (bool f);
virtual void ScheduleClose (bool after_writing);
virtual void HandleError();
void SetNotifyReadable (bool);
void SetNotifyWritable (bool);
void SetAttached (bool);
void SetWatchOnly (bool);
bool Pause();
bool Resume();
bool IsNotifyReadable(){ return bNotifyReadable; }
bool IsNotifyWritable(){ return bNotifyWritable; }
virtual void Read();
virtual void Write();
virtual void Heartbeat();
virtual bool SelectForRead();
virtual bool SelectForWrite();
// Do we have any data to write? This is used by ShouldDelete.
virtual int GetOutboundDataSize() {return OutboundDataSize;}
virtual void StartTls();
virtual void SetTlsParms (const char *, const char *, bool, bool, const char *, const char *, const char *, const char *, int);
#ifdef WITH_SSL
virtual X509 *GetPeerCert();
virtual int GetCipherBits();
virtual const char *GetCipherName();
virtual const char *GetCipherProtocol();
virtual const char *GetSNIHostname();
virtual bool VerifySslPeer(const char*);
virtual void AcceptSslPeer();
#endif
void SetServerMode() {bIsServer = true;}
virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); }
virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); }
virtual uint64_t GetCommInactivityTimeout();
virtual int SetCommInactivityTimeout (uint64_t value);
virtual int ReportErrorStatus();
virtual bool IsConnectPending(){ return bConnectPending; }
protected:
struct OutboundPage {
OutboundPage (const char *b, int l, int o=0): Buffer(b), Length(l), Offset(o) {}
void Free() {if (Buffer) free (const_cast<char*>(Buffer)); }
const char *Buffer;
int Length;
int Offset;
};
protected:
bool bConnectPending;
bool bNotifyReadable;
bool bNotifyWritable;
bool bReadAttemptedAfterClose;
bool bWriteAttemptedAfterClose;
std::deque<OutboundPage> OutboundPages;
int OutboundDataSize;
#ifdef WITH_SSL
SslBox_t *SslBox;
std::string CertChainFilename;
std::string PrivateKeyFilename;
std::string CipherList;
std::string EcdhCurve;
std::string DhParam;
int Protocols;
bool bHandshakeSignaled;
bool bSslVerifyPeer;
bool bSslFailIfNoPeerCert;
std::string SniHostName;
bool bSslPeerAccepted;
#endif
#ifdef HAVE_KQUEUE
bool bGotExtraKqueueEvent;
#endif
bool bIsServer;
private:
void _UpdateEvents();
void _UpdateEvents(bool, bool);
void _WriteOutboundData();
void _DispatchInboundData (const char *buffer, unsigned long size);
void _DispatchCiphertext();
int _SendRawOutboundData (const char *buffer, unsigned long size);
void _CheckHandshakeStatus();
};
/************************
class DatagramDescriptor
************************/
class DatagramDescriptor: public EventableDescriptor
{
public:
DatagramDescriptor (SOCKET, EventMachine_t*);
virtual ~DatagramDescriptor();
virtual void Read();
virtual void Write();
virtual void Heartbeat();
virtual bool SelectForRead() {return true;}
virtual bool SelectForWrite();
int SendOutboundData (const char*, unsigned long);
int SendOutboundDatagram (const char*, unsigned long, const char*, int);
// Do we have any data to write? This is used by ShouldDelete.
virtual int GetOutboundDataSize() {return OutboundDataSize;}
virtual bool GetPeername (struct sockaddr* s, socklen_t* len);
virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); };
virtual uint64_t GetCommInactivityTimeout();
virtual int SetCommInactivityTimeout (uint64_t value);
protected:
struct OutboundPage {
OutboundPage (const char *b, int l, struct sockaddr_in6 f, int o=0): Buffer(b), Length(l), Offset(o), From(f) {}
void Free() {if (Buffer) free (const_cast<char*>(Buffer)); }
const char *Buffer;
int Length;
int Offset;
struct sockaddr_in6 From;
};
std::deque<OutboundPage> OutboundPages;
int OutboundDataSize;
struct sockaddr_in6 ReturnAddress;
};
/************************
class AcceptorDescriptor
************************/
class AcceptorDescriptor: public EventableDescriptor
{
public:
AcceptorDescriptor (SOCKET, EventMachine_t*);
virtual ~AcceptorDescriptor();
virtual void Read();
virtual void Write();
virtual void Heartbeat();
virtual bool SelectForRead() {return true;}
virtual bool SelectForWrite() {return false;}
virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); }
virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); };
static void StopAcceptor (const uintptr_t binding);
};
/********************
class PipeDescriptor
********************/
#ifdef OS_UNIX
class PipeDescriptor: public EventableDescriptor
{
public:
PipeDescriptor (SOCKET, pid_t, EventMachine_t*);
virtual ~PipeDescriptor() NO_EXCEPT_FALSE;
virtual void Read();
virtual void Write();
virtual void Heartbeat();
virtual bool SelectForRead();
virtual bool SelectForWrite();
int SendOutboundData (const char*, unsigned long);
virtual int GetOutboundDataSize() {return OutboundDataSize;}
virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); }
virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); }
virtual bool GetSubprocessPid (pid_t*);
protected:
struct OutboundPage {
OutboundPage (const char *b, int l, int o=0): Buffer(b), Length(l), Offset(o) {}
void Free() {if (Buffer) free (const_cast<char*>(Buffer)); }
const char *Buffer;
int Length;
int Offset;
};
protected:
bool bReadAttemptedAfterClose;
std::deque<OutboundPage> OutboundPages;
int OutboundDataSize;
pid_t SubprocessPid;
private:
void _DispatchInboundData (const char *buffer, int size);
};
#endif // OS_UNIX
/************************
class KeyboardDescriptor
************************/
class KeyboardDescriptor: public EventableDescriptor
{
public:
KeyboardDescriptor (EventMachine_t*);
virtual ~KeyboardDescriptor();
virtual void Read();
virtual void Write();
virtual void Heartbeat();
virtual bool SelectForRead() {return true;}
virtual bool SelectForWrite() {return false;}
virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); }
virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); }
protected:
bool bReadAttemptedAfterClose;
private:
void _DispatchInboundData (const char *buffer, int size);
};
/***********************
class InotifyDescriptor
************************/
class InotifyDescriptor: public EventableDescriptor
{
public:
InotifyDescriptor (EventMachine_t*);
virtual ~InotifyDescriptor();
void Read();
void Write();
virtual void Heartbeat() {}
virtual bool SelectForRead() {return true;}
virtual bool SelectForWrite() {return false;}
virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return false; }
virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return false; }
};
#endif // __EventableDescriptor__H_