From 54cacecab4b1e16e52579f84125be6e6ea13f5a4 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 4 Feb 2019 11:43:22 -0500 Subject: [PATCH 01/14] IoHandle interface Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 62 +++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index c00c2288278dd..8515ac6494e63 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -7,27 +7,73 @@ namespace Envoy { namespace Network { +template struct IoHandleCallResult { + T rc_; + int errno_; +}; + +typedef IoHandleCallResult IoHandleCallIntResult; +typedef IoHandleCallResult IoHandleCallSizeResult; + /** * IoHandle: an abstract interface for all I/O operations */ class IoHandle { public: - IoHandle() {} - virtual ~IoHandle() {} /** - * Return data associated with IoHandle. - * - * TODO(sbelair2) remove fd() method + * Clean up IoHandle resources */ - virtual int fd() const PURE; + virtual IoHandleCallIntResult close() PURE; + + virtual bool isClosed() PURE; + + virtual IoHandleCallSizeResult readv(const iovec* iovec, int num_iovec) PURE; + + virtual IoHandleCallSizeResult writev(const iovec* iovec, int num_iovec) PURE; + + virtual IoHandleCallIntResult bind(const Network::Address::Instance& address) PURE; + + virtual IoHandleCallIntResult connect(const Network::Address::Instance& server_address) PURE; /** - * Clean up IoHandle resources + * Wrap setsockopt() + */ + virtual IoHandleCallIntResult setIoHandleOption(int level, int optname, const void* optval, + socklen_t optlen) PURE; + /** + * Wrap getsockopt() + */ + virtual IoHandleCallIntResult getIoHandleOption(int level, int optname, void* optval, + socklen_t* optlen) PURE; + + /** + * Wrap getsockname() + */ + virtual IoHandleCallIntResult getIoHandleName(const Network::Address::Instance& address) PURE; + + virtual IoHandleCallIntResult getPeerName(const Network::Address::Instance& address) PURE; + + /** + * Wrap fcntl(fd_, F_SETFL...) + */ + virtual IoHandleCallIntResult setIoHandleFlag(int flag) PURE; + /** + * Wrap fcntl(fd_, F_GETFL...) */ - virtual void close() PURE; + virtual IoHandleCallIntResult getIoHandleFlag() PURE; + + virtual IoHandleCallIntResult listen(int backlog) PURE; + + /** + * Wrap dup() + */ + virtual IoHandlePtr dup() PURE; + + virtual IoHandleCallIntResult shutdown(int how) PURE; }; + typedef std::unique_ptr IoHandlePtr; } // namespace Network From 8dc3b1361325e02334d393e23388c3df477ed2bd Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 4 Feb 2019 12:22:12 -0500 Subject: [PATCH 02/14] fix compile error Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 8515ac6494e63..7b1c783577a69 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -69,7 +69,7 @@ class IoHandle { /** * Wrap dup() */ - virtual IoHandlePtr dup() PURE; + virtual std::unique_ptr dup() PURE; virtual IoHandleCallIntResult shutdown(int how) PURE; }; From c6bd520369644fdcca1fc04cc24813f79190c0e2 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 4 Feb 2019 13:45:42 -0500 Subject: [PATCH 03/14] forward declare address Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 7b1c783577a69..9feb1814276c2 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -3,6 +3,9 @@ #include #include "envoy/common/pure.h" +#include "envoy/network/address.h" + +class Network::Address::Instance; namespace Envoy { namespace Network { From 2315a7f1e260a571954f333f6b9461b8fcd7f74a Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 4 Feb 2019 14:17:21 -0500 Subject: [PATCH 04/14] fix inlcude Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 9feb1814276c2..ea4215782ac1f 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -3,13 +3,14 @@ #include #include "envoy/common/pure.h" -#include "envoy/network/address.h" - -class Network::Address::Instance; namespace Envoy { namespace Network { +namespace Address { +class Instance; +} // namespace Address + template struct IoHandleCallResult { T rc_; int errno_; @@ -25,6 +26,16 @@ class IoHandle { public: virtual ~IoHandle() {} + /** + * Return data associated with IoHandle. + * + * TODO(sbelair2) remove fd() method + * We probably still need some method similar to this one for + * evconnlistener_new(). Or We can move it to IoSocketHandle and down cast the + * IoHandle to IoSocketHandle wherever needed. + */ + virtual int fd() const PURE; + /** * Clean up IoHandle resources */ From 800bf4a8c2708817eae23d57c13f55bcc8fab519 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 4 Feb 2019 14:18:53 -0500 Subject: [PATCH 05/14] format Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index ea4215782ac1f..830c361fdc961 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -9,7 +9,7 @@ namespace Network { namespace Address { class Instance; -} // namespace Address +} // namespace Address template struct IoHandleCallResult { T rc_; From ebe783d1732e2064c749e125ee1b5ad73cb0ca14 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 4 Feb 2019 17:06:14 -0500 Subject: [PATCH 06/14] make destructor virtual Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 830c361fdc961..5d662f7b9b471 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -11,7 +11,13 @@ namespace Address { class Instance; } // namespace Address +/** + * Basic type for return result which has a return code and error code defined + * according to different implementation. + */ template struct IoHandleCallResult { + virtual ~IoHandleCallResult() {} + T rc_; int errno_; }; From 3621f3a0f4a35496f336ada663092c2cc121ab38 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Thu, 7 Feb 2019 10:44:55 -0500 Subject: [PATCH 07/14] abstract more types Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 67 ++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 5d662f7b9b471..90d6256528b4e 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -1,16 +1,41 @@ #pragma once +#include #include #include "envoy/common/pure.h" namespace Envoy { + +namespace Buffer { +struct RawSlice; +} + namespace Network { namespace Address { class Instance; } // namespace Address +class IoError { +public: + enum IoErrorCode { + IO_NO_ERROR = 0, + IO_EAGAIN, + IO_ENOTSUP, + IO_EAFNOSUPPORT, + IO_EINPROGRESS, + IO_EPERM, + IO_UNKNOWN_ERROR + }; + virtual ~IoError() {} + + // Map platform specific error into IoErrorCode. + virtual IoErrorCode getErrorCode() PURE; + + virtual std::string getErrorDetails() PURE; +}; + /** * Basic type for return result which has a return code and error code defined * according to different implementation. @@ -19,17 +44,28 @@ template struct IoHandleCallResult { virtual ~IoHandleCallResult() {} T rc_; - int errno_; + std::unique_ptr err_; }; -typedef IoHandleCallResult IoHandleCallIntResult; -typedef IoHandleCallResult IoHandleCallSizeResult; +using IoHandleCallIntResult = IoHandleCallResult; +using IoHandleCallSizeResult = IoHandleCallResult; /** * IoHandle: an abstract interface for all I/O operations */ class IoHandle { public: + enum ShutdownType { + READ = 0, + WRITE, + BOTH + }; + + enum IoHandleFlag { + NONBLOCK = 1, + APPEND = 2 + }; + virtual ~IoHandle() {} /** @@ -49,9 +85,15 @@ class IoHandle { virtual bool isClosed() PURE; - virtual IoHandleCallSizeResult readv(const iovec* iovec, int num_iovec) PURE; + virtual IoHandleCallSizeResult readv(Buffer::RawSlice* iovecs, int num_iovec) PURE; + + virtual IoHandleCallIntResult recvmmsg(struct mmsghdr *msgvec, unsigned int vlen, + int flags, struct timespec *timeout) PURE; + + virtual IoHandleCallSizeResult writev(const Buffer::RawSlice* iovec, int num_iovec) PURE; - virtual IoHandleCallSizeResult writev(const iovec* iovec, int num_iovec) PURE; + virtual IoHandleCallIntResult sendmmsg(struct mmsghdr* msgvec, unsigned int vlen, + int flags) PURE; virtual IoHandleCallIntResult bind(const Network::Address::Instance& address) PURE; @@ -69,20 +111,23 @@ class IoHandle { socklen_t* optlen) PURE; /** - * Wrap getsockname() + * Wrap Address::addressFromFd() */ - virtual IoHandleCallIntResult getIoHandleName(const Network::Address::Instance& address) PURE; + virtual IoHandleCallIntResult getBindToAddress(Network::Address::Instance** address) PURE; - virtual IoHandleCallIntResult getPeerName(const Network::Address::Instance& address) PURE; + /** + * Wrap Address::peerAddressFromFd() + */ + virtual IoHandleCallIntResult getPeerAddress(Network::Address::Instance** address) PURE; /** * Wrap fcntl(fd_, F_SETFL...) */ - virtual IoHandleCallIntResult setIoHandleFlag(int flag) PURE; + virtual IoHandleCallIntResult setIoHandleFlag(std::bitset<2> flag) PURE; /** * Wrap fcntl(fd_, F_GETFL...) */ - virtual IoHandleCallIntResult getIoHandleFlag() PURE; + virtual IoHandleCallResult> getIoHandleFlags() PURE; virtual IoHandleCallIntResult listen(int backlog) PURE; @@ -91,7 +136,7 @@ class IoHandle { */ virtual std::unique_ptr dup() PURE; - virtual IoHandleCallIntResult shutdown(int how) PURE; + virtual IoHandleCallIntResult shutdown(ShutdownType how) PURE; }; typedef std::unique_ptr IoHandlePtr; From 47109ecc88db177d7706191142775f828600d72e Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Thu, 7 Feb 2019 10:58:14 -0500 Subject: [PATCH 08/14] format Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 90d6256528b4e..1bf6b3653cdfc 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -32,7 +32,7 @@ class IoError { // Map platform specific error into IoErrorCode. virtual IoErrorCode getErrorCode() PURE; - + virtual std::string getErrorDetails() PURE; }; @@ -55,16 +55,9 @@ using IoHandleCallSizeResult = IoHandleCallResult; */ class IoHandle { public: - enum ShutdownType { - READ = 0, - WRITE, - BOTH - }; + enum ShutdownType { READ = 0, WRITE, BOTH }; - enum IoHandleFlag { - NONBLOCK = 1, - APPEND = 2 - }; + enum IoHandleFlag { NONBLOCK = 1, APPEND = 2 }; virtual ~IoHandle() {} @@ -87,13 +80,12 @@ class IoHandle { virtual IoHandleCallSizeResult readv(Buffer::RawSlice* iovecs, int num_iovec) PURE; - virtual IoHandleCallIntResult recvmmsg(struct mmsghdr *msgvec, unsigned int vlen, - int flags, struct timespec *timeout) PURE; + virtual IoHandleCallIntResult recvmmsg(struct mmsghdr* msgvec, unsigned int vlen, int flags, + struct timespec* timeout) PURE; virtual IoHandleCallSizeResult writev(const Buffer::RawSlice* iovec, int num_iovec) PURE; - virtual IoHandleCallIntResult sendmmsg(struct mmsghdr* msgvec, unsigned int vlen, - int flags) PURE; + virtual IoHandleCallIntResult sendmmsg(struct mmsghdr* msgvec, unsigned int vlen, int flags) PURE; virtual IoHandleCallIntResult bind(const Network::Address::Instance& address) PURE; From 9139a8991fe17f29ff50f42a569bca85c3bbd1ae Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Fri, 8 Feb 2019 13:17:35 -0500 Subject: [PATCH 09/14] rename enum's Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 1bf6b3653cdfc..d36ab0418122c 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -19,14 +19,14 @@ class Instance; class IoError { public: - enum IoErrorCode { - IO_NO_ERROR = 0, - IO_EAGAIN, - IO_ENOTSUP, - IO_EAFNOSUPPORT, - IO_EINPROGRESS, - IO_EPERM, - IO_UNKNOWN_ERROR + enum class IoErrorCode { + NoError = 0, + Again, + NoSupport, + AddressFamilyNoSupport, + InProgress, + Permission, + UnknownError }; virtual ~IoError() {} @@ -38,7 +38,7 @@ class IoError { /** * Basic type for return result which has a return code and error code defined - * according to different implementation. + * according to different implementations. */ template struct IoHandleCallResult { virtual ~IoHandleCallResult() {} @@ -55,9 +55,9 @@ using IoHandleCallSizeResult = IoHandleCallResult; */ class IoHandle { public: - enum ShutdownType { READ = 0, WRITE, BOTH }; + enum class ShutdownType { Read = 0, Write, Both }; - enum IoHandleFlag { NONBLOCK = 1, APPEND = 2 }; + enum class IoHandleFlag { NonBlock = 1, Append = 2 }; virtual ~IoHandle() {} From d50cc2ad857bac711e9cd71e218ed574e12f3230 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Fri, 8 Feb 2019 14:44:40 -0500 Subject: [PATCH 10/14] add const Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index d36ab0418122c..328e873b44e3d 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -31,9 +31,9 @@ class IoError { virtual ~IoError() {} // Map platform specific error into IoErrorCode. - virtual IoErrorCode getErrorCode() PURE; + virtual IoErrorCode getErrorCode() const PURE; - virtual std::string getErrorDetails() PURE; + virtual std::string getErrorDetails() const PURE; }; /** From 658fceb0b63582b002e6e56821f7592c4f07b9a7 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 11 Feb 2019 16:17:09 -0500 Subject: [PATCH 11/14] document enum Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 328e873b44e3d..1521dfaad8ad1 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -9,7 +9,7 @@ namespace Envoy { namespace Buffer { struct RawSlice; -} +} // namespace Buffer namespace Network { @@ -20,12 +20,19 @@ class Instance; class IoError { public: enum class IoErrorCode { + // Success. NoError = 0, + // No data available right now, try again later. Again, + // Not supported. NoSupport, + // Address family not supported. AddressFamilyNoSupport, + // During non-blocking connect, the connection cannot be completed immediately. InProgress, + // Permission denied. Permission, + // Other error codes cannot be mapped to any one above in getErrorCode(). UnknownError }; virtual ~IoError() {} @@ -114,6 +121,10 @@ class IoHandle { /** * Wrap fcntl(fd_, F_SETFL...) + * @param flag each bit stands for a flag in enum IoHandleFlag. From low bit + * to high bit: + * 1st -- NonBlock + * 2nd -- Append */ virtual IoHandleCallIntResult setIoHandleFlag(std::bitset<2> flag) PURE; /** From d02c020589b347dbdd9102131439dfe53f7662d8 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 11 Feb 2019 17:11:02 -0500 Subject: [PATCH 12/14] use binary literal Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 1521dfaad8ad1..087ef4d7c026c 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -64,17 +64,15 @@ class IoHandle { public: enum class ShutdownType { Read = 0, Write, Both }; - enum class IoHandleFlag { NonBlock = 1, Append = 2 }; + enum class IoHandleFlag { NonBlock = 0b1, Append = 0b10 }; virtual ~IoHandle() {} /** * Return data associated with IoHandle. * - * TODO(sbelair2) remove fd() method - * We probably still need some method similar to this one for - * evconnlistener_new(). Or We can move it to IoSocketHandle and down cast the - * IoHandle to IoSocketHandle wherever needed. + * TODO(danzh) move it to IoSocketHandle after replacing the calls to it with + * calls to IoHandle API's everywhere. */ virtual int fd() const PURE; @@ -121,10 +119,7 @@ class IoHandle { /** * Wrap fcntl(fd_, F_SETFL...) - * @param flag each bit stands for a flag in enum IoHandleFlag. From low bit - * to high bit: - * 1st -- NonBlock - * 2nd -- Append + * @param flag each bit stands for a flag in enum IoHandleFlag. */ virtual IoHandleCallIntResult setIoHandleFlag(std::bitset<2> flag) PURE; /** From 2b6abc727fd344278de025238427102807627e67 Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Mon, 11 Feb 2019 17:33:17 -0500 Subject: [PATCH 13/14] format Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index 087ef4d7c026c..f7d5875559328 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -64,7 +64,11 @@ class IoHandle { public: enum class ShutdownType { Read = 0, Write, Both }; - enum class IoHandleFlag { NonBlock = 0b1, Append = 0b10 }; + enum class IoHandleFlag { + // Each of these maps to a unique bit. + NonBlock = 0b01, + Append = 0b10 + }; virtual ~IoHandle() {} From 096c1e333e6b04c569aeba2af2f6ec217cd2752a Mon Sep 17 00:00:00 2001 From: Dan Zhang Date: Thu, 21 Feb 2019 16:27:16 -0500 Subject: [PATCH 14/14] update IoError Signed-off-by: Dan Zhang --- include/envoy/network/io_handle.h | 36 ++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index f7d5875559328..3155f7f689c5c 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -17,11 +17,17 @@ namespace Address { class Instance; } // namespace Address +class IoError; + +// IoErrorCode::Again is used frequently. Define it to be a distinguishable address to avoid +// frequent memory allocation of IoError instance. +// If this is used, IoHandleCallResult has to be instantiated with a deleter that does not +// deallocate memory for this error. +#define ENVOY_ERROR_AGAIN reinterpret_cast(0x01) + class IoError { public: enum class IoErrorCode { - // Success. - NoError = 0, // No data available right now, try again later. Again, // Not supported. @@ -37,21 +43,45 @@ class IoError { }; virtual ~IoError() {} + // Map platform specific error into IoErrorCode. + // Needed to hide errorCode() in case of ENVOY_ERROR_AGAIN. + static IoErrorCode getErrorCode(const IoError& err) { + if (&err == ENVOY_ERROR_AGAIN) { + return IoErrorCode::Again; + } + return err.errorCode(); + } + + static std::string getErrorDetails(const IoError& err) { + if (&err == ENVOY_ERROR_AGAIN) { + return "Try again later"; + } + return err.errorDetails(); + } + +protected: // Map platform specific error into IoErrorCode. virtual IoErrorCode getErrorCode() const PURE; virtual std::string getErrorDetails() const PURE; }; +using IoErrorDeleterType = void (*)(IoError*); +using IoErrorPtr = std::unique_ptr; + /** * Basic type for return result which has a return code and error code defined * according to different implementations. + * If the call succeeds, |err_| is nullptr and |rc_| is valid. Otherwise |err_| + * can be passed into IoError::getErrorCode() to extract the error. In this + * case, |rc_| is invalid. */ template struct IoHandleCallResult { + IoHandleCallResult(T rc, IoErrorPtr err) : rc_(rc), err_(std::move(err)) {} virtual ~IoHandleCallResult() {} T rc_; - std::unique_ptr err_; + IoErrorPtr err_; }; using IoHandleCallIntResult = IoHandleCallResult;