diff options
author | Ossama Othman <ossama-othman@users.noreply.github.com> | 2001-07-13 19:21:42 +0000 |
---|---|---|
committer | Ossama Othman <ossama-othman@users.noreply.github.com> | 2001-07-13 19:21:42 +0000 |
commit | 59036db4f6fad92d7bf23fa3ca516847a3cdbe3a (patch) | |
tree | ba16905391038b4dfa8a44d952fd4c17c6702d82 /ace/SSL | |
parent | 17e28db7344cf2144f5a416e779ef620f9911758 (diff) | |
download | ATCD-59036db4f6fad92d7bf23fa3ca516847a3cdbe3a.tar.gz |
ChangeLogTag:Fri Jul 13 12:16:03 2001 Ossama Othman <ossama@uci.edu>
Diffstat (limited to 'ace/SSL')
-rw-r--r-- | ace/SSL/ACE_SSL.dsp | 20 | ||||
-rw-r--r-- | ace/SSL/Makefile | 257 | ||||
-rw-r--r-- | ace/SSL/Makefile.bor | 4 | ||||
-rw-r--r-- | ace/SSL/SSL_Asynch_BIO.cpp | 199 | ||||
-rw-r--r-- | ace/SSL/SSL_Asynch_BIO.h | 50 | ||||
-rw-r--r-- | ace/SSL/SSL_Asynch_Stream.cpp | 1110 | ||||
-rw-r--r-- | ace/SSL/SSL_Asynch_Stream.h | 236 |
7 files changed, 1870 insertions, 6 deletions
diff --git a/ace/SSL/ACE_SSL.dsp b/ace/SSL/ACE_SSL.dsp index 183f2bf5bfe..68950f476a2 100644 --- a/ace/SSL/ACE_SSL.dsp +++ b/ace/SSL/ACE_SSL.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ACE_SSL_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../" /D "NDEBUG" /D "_WINDOWS" /D "WIN32" /D "ACE_SSL_BUILD_DLL" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../" /I "$(OPENSSL_ROOT)\inc32" /D "NDEBUG" /D "_WINDOWS" /D "WIN32" /D "ACE_SSL_BUILD_DLL" /FD /c
# SUBTRACT CPP /X /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 ace.lib libeay32.lib ssleay32.lib /nologo /dll /pdb:none /machine:I386 /out:"..\..\bin\ACE_SSL.dll" /libpath:"../"
+# ADD LINK32 ace.lib libeay32.lib ssleay32.lib /nologo /dll /pdb:none /machine:I386 /out:"..\..\bin\ACE_SSL.dll" /libpath:"../" /libpath:"$(OPENSSL_ROOT)\out32dll"
!ELSEIF "$(CFG)" == "ACE_SSL - Win32 Debug"
@@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ACE_SSL_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ACE_SSL_BUILD_DLL" /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../../" /I "$(OPENSSL_ROOT)\inc32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ACE_SSL_BUILD_DLL" /FD /c
# SUBTRACT CPP /Fr /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
@@ -81,7 +81,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib libeay32.lib ssleay32.lib /nologo /dll /debug /machine:I386 /out:"..\..\bin\ACE_SSLd.dll" /libpath:"../"
+# ADD LINK32 aced.lib libeay32.lib ssleay32.lib /nologo /dll /debug /machine:I386 /out:"..\..\bin\ACE_SSLd.dll" /libpath:"../" /libpath:"$(OPENSSL_ROOT)\out32dll.dbg"
# SUBTRACT LINK32 /pdb:none
!ENDIF
@@ -99,6 +99,14 @@ SOURCE=.\SSL_Accept_Handler.cpp # End Source File
# Begin Source File
+SOURCE=.\SSL_Asynch_BIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SSL_Asynch_Stream.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\SSL_Connect_Handler.cpp
# End Source File
# Begin Source File
@@ -131,6 +139,10 @@ SOURCE=.\SSL_Accept_Handler.h # End Source File
# Begin Source File
+SOURCE=.\SSL_Asynch_Stream.h
+# End Source File
+# Begin Source File
+
SOURCE=.\SSL_Connect_Handler.h
# End Source File
# Begin Source File
diff --git a/ace/SSL/Makefile b/ace/SSL/Makefile index 70530f7d170..07b758b9b23 100644 --- a/ace/SSL/Makefile +++ b/ace/SSL/Makefile @@ -21,7 +21,9 @@ FILES = \ SSL_SOCK_Connector \ SSL_SOCK_Stream \ SSL_Accept_Handler \ - SSL_Connect_Handler + SSL_Connect_Handler \ + SSL_Asynch_Stream \ + SSL_Asynch_BIO LSRC = $(addsuffix .cpp,$(FILES)) @@ -631,4 +633,257 @@ endif # HPUX_VERS $(ACE_ROOT)/ace/SOCK_Stream.i \ SSL_SOCK_Stream.i +.obj/SSL_Asynch_Stream.o .obj/SSL_Asynch_Stream.so .shobj/SSL_Asynch_Stream.o .shobj/SSL_Asynch_Stream.so: SSL_Asynch_Stream.cpp SSL_Asynch_Stream.h \ + $(ACE_ROOT)/ace/pre.h SSL_Context.h \ + SSL_Export.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/svc_export.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Synch_T.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Singleton.cpp \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Managed_Object.cpp \ + SSL_Context.i \ + $(ACE_ROOT)/ace/Asynch_IO_Impl.h \ + $(ACE_ROOT)/ace/Asynch_IO.h \ + $(ACE_ROOT)/ace/Asynch_IO_Impl.i \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_Allocator.h \ + $(ACE_ROOT)/ace/Malloc_Allocator.i \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Free_List.cpp \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Malloc_T.cpp \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Unbounded_Set.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Unbounded_Set.inl \ + $(ACE_ROOT)/ace/Unbounded_Set.cpp \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + SSL_Asynch_BIO.h \ + $(ACE_ROOT)/ace/POSIX_Proactor.h \ + $(ACE_ROOT)/ace/Proactor_Impl.h \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Test_and_Set.h \ + $(ACE_ROOT)/ace/Test_and_Set.i \ + $(ACE_ROOT)/ace/Test_and_Set.cpp \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.cpp \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Pipe.h \ + $(ACE_ROOT)/ace/Pipe.i \ + $(ACE_ROOT)/ace/POSIX_Asynch_IO.h \ + $(ACE_ROOT)/ace/POSIX_Asynch_IO.i \ + $(ACE_ROOT)/ace/Unbounded_Queue.h \ + $(ACE_ROOT)/ace/Unbounded_Queue.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.cpp \ + $(ACE_ROOT)/ace/POSIX_Proactor.i \ + $(ACE_ROOT)/ace/Proactor.h \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Containers_T.h \ + $(ACE_ROOT)/ace/Array_Base.h \ + $(ACE_ROOT)/ace/Array_Base.inl \ + $(ACE_ROOT)/ace/Array_Base.cpp \ + $(ACE_ROOT)/ace/Containers_T.i \ + $(ACE_ROOT)/ace/Containers_T.cpp \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Timer_List.h \ + $(ACE_ROOT)/ace/Timer_List_T.h \ + $(ACE_ROOT)/ace/Timer_List_T.cpp \ + $(ACE_ROOT)/ace/Timer_Heap.h \ + $(ACE_ROOT)/ace/Timer_Heap_T.h \ + $(ACE_ROOT)/ace/Timer_Heap_T.cpp \ + $(ACE_ROOT)/ace/Timer_Wheel.h \ + $(ACE_ROOT)/ace/Timer_Wheel_T.h \ + $(ACE_ROOT)/ace/Timer_Wheel_T.cpp \ + $(ACE_ROOT)/ace/High_Res_Timer.h \ + $(ACE_ROOT)/ace/High_Res_Timer.i + +.obj/SSL_Asynch_BIO.o .obj/SSL_Asynch_BIO.so .shobj/SSL_Asynch_BIO.o .shobj/SSL_Asynch_BIO.so: SSL_Asynch_BIO.cpp SSL_Asynch_BIO.h \ + $(ACE_ROOT)/ace/pre.h SSL_Export.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/svc_export.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + SSL_Asynch_Stream.h SSL_Context.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/streams.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Synch_T.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Log_Record.i \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Singleton.cpp \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Managed_Object.cpp \ + SSL_Context.i \ + $(ACE_ROOT)/ace/Asynch_IO_Impl.h \ + $(ACE_ROOT)/ace/Asynch_IO.h \ + $(ACE_ROOT)/ace/Asynch_IO_Impl.i \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Malloc.h \ + $(ACE_ROOT)/ace/Malloc.i \ + $(ACE_ROOT)/ace/Malloc_T.h \ + $(ACE_ROOT)/ace/Malloc_Allocator.h \ + $(ACE_ROOT)/ace/Malloc_Allocator.i \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Free_List.cpp \ + $(ACE_ROOT)/ace/Malloc_T.i \ + $(ACE_ROOT)/ace/Malloc_T.cpp \ + $(ACE_ROOT)/ace/Memory_Pool.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Mem_Map.h \ + $(ACE_ROOT)/ace/Mem_Map.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \ + $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \ + $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \ + $(ACE_ROOT)/ace/Unbounded_Set.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Unbounded_Set.inl \ + $(ACE_ROOT)/ace/Unbounded_Set.cpp \ + $(ACE_ROOT)/ace/Memory_Pool.i \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp + # IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/ace/SSL/Makefile.bor b/ace/SSL/Makefile.bor index 36609d8c2c8..def407edb06 100644 --- a/ace/SSL/Makefile.bor +++ b/ace/SSL/Makefile.bor @@ -14,7 +14,9 @@ OBJFILES = \ $(OBJDIR)\SSL_SOCK_Connector.obj \ $(OBJDIR)\SSL_SOCK_Stream.obj \ $(OBJDIR)\SSL_Accept_Handler.obj \ - $(OBJDIR)\SSL_Connect_Handler.obj + $(OBJDIR)\SSL_Connect_Handler.obj \ + $(OBJDIR)\SSL_Asynch_Stream.obj \ + $(OBJDIR)\SSL_Asynch_BIO.obj CFLAGS = $(ACE_CFLAGS) $(SSL_CFLAGS) $(ACE_SSL_CFLAGS) -DACE_SSL_BUILD_DLL diff --git a/ace/SSL/SSL_Asynch_BIO.cpp b/ace/SSL/SSL_Asynch_BIO.cpp new file mode 100644 index 00000000000..c1b098c43e0 --- /dev/null +++ b/ace/SSL/SSL_Asynch_BIO.cpp @@ -0,0 +1,199 @@ +// -*- C++ -*- + + +#include "SSL_Asynch_BIO.h" +#include "SSL_Asynch_Stream.h" + +ACE_RCSID (ACE_SSL, + SSL_Asynch_BIO, + "$Id$") + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)) + +#define BIO_TYPE_ACE ( 21 | BIO_TYPE_SOURCE_SINK ) + +static BIO_METHOD methods_ACE = + { + BIO_TYPE_ACE , // BIO_TYPE_PROXY_SERVER, + "ACE_Asynch_BIO", + ACE_Asynch_BIO_write, + ACE_Asynch_BIO_read, + ACE_Asynch_BIO_puts, + NULL, /* ACE_Asynch_BIO_gets, */ + ACE_Asynch_BIO_ctrl, + ACE_Asynch_BIO_new, + ACE_Asynch_BIO_free, + NULL, + }; + +BIO_METHOD * +BIO_s_ACE_Asynch (void) +{ + return (&methods_ACE); +} + +BIO * +BIO_new_ACE_Asynch (void *ssl_asynch_stream) +{ + BIO * pBIO = BIO_new (BIO_s_ACE_Asynch ()); + + if (pBIO) + BIO_ctrl (pBIO, + BIO_C_SET_FILE_PTR, + 0, + ssl_asynch_stream); + + return pBIO; +} + +int +ACE_Asynch_BIO_new (BIO *pBIO) +{ + pBIO->init = 0; // not initialized + pBIO->num = 0; // still zero ( we can use it ) + pBIO->ptr = 0; // will be pointer to ACE_SSL_Asynch_Stream + pBIO->flags = 0; // + + return 1; +} + +int +ACE_Asynch_BIO_free (BIO *pBIO) +{ + if (pBIO == 0) + return 0; + + if (pBIO->shutdown) + { + pBIO->ptr = 0; + pBIO->init = 0; + pBIO->num = 0; + pBIO->flags = 0; + } + + return 1; +} + +int +ACE_Asynch_BIO_read (BIO * pBIO, char * buf, int len) +{ + BIO_clear_retry_flags (pBIO); + + ACE_SSL_Asynch_Stream * p_stream = + ACE_static_cast (ACE_SSL_Asynch_Stream *, pBIO->ptr); + + if (pBIO->init == 0 || p_stream == 0) + return -1; + + if (buf == 0) + return -1; + + if (len <= 0 ) + return -1; + + BIO_clear_retry_flags (pBIO); + + int errval = 0; + + int retval = + p_stream->ssl_bio_read (buf, + ACE_static_cast (size_t, len), + errval); + + if (retval >= 0) + return retval; + + if (errval == EINPROGRESS) + BIO_set_retry_read (pBIO); + + return -1; +} + +int +ACE_Asynch_BIO_write (BIO * pBIO, const char * buf, int len) +{ + BIO_clear_retry_flags (pBIO); + + ACE_SSL_Asynch_Stream * p_stream = + ACE_static_cast (ACE_SSL_Asynch_Stream *, pBIO->ptr); + + if (pBIO->init == 0 || p_stream == 0) + return -1; + + if (buf == 0) + return -1; + + if (len <= 0) + return -1; + + BIO_clear_retry_flags (pBIO); + + int errval = 0; + + int retval = + p_stream->ssl_bio_write (buf, + ACE_static_cast (size_t, len), + errval); + + if (retval >= 0) + return retval; + + if (errval == EINPROGRESS) + BIO_set_retry_write (pBIO); + + return -1; +} + +long +ACE_Asynch_BIO_ctrl (BIO * pBIO, int cmd, long num, void *ptr) +{ + long ret = 1; + + switch (cmd) + { + case BIO_C_SET_FILE_PTR: + pBIO->shutdown = ACE_static_cast (int, num); + pBIO->ptr = ptr; + pBIO->init = 1; + break; + + case BIO_CTRL_INFO: + ret = 0; + break; + + case BIO_CTRL_GET_CLOSE: + ret = pBIO->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + pBIO->shutdown = ACE_static_cast (int, num); + break; + + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + + default: + ret = 0; + break; + } + + return ret; +} + + +int +ACE_Asynch_BIO_puts (BIO *pBIO, const char *str) +{ + int n = ACE_OS::strlen (str); + + return ACE_Asynch_BIO_write (pBIO, str, n); +} + +#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS*/ diff --git a/ace/SSL/SSL_Asynch_BIO.h b/ace/SSL/SSL_Asynch_BIO.h new file mode 100644 index 00000000000..92fbdb4c110 --- /dev/null +++ b/ace/SSL/SSL_Asynch_BIO.h @@ -0,0 +1,50 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file SSL_Asynch_BIO.h + * + * $Id$ + * + * @author Alexander Libman <alibman@baltimore.com> + * @author Ossama Othman <ossama@uci.edu> + * + */ +//============================================================================= + +#ifndef ACE_SSL_ASYNCH_BIO_H +#define ACE_SSL_ASYNCH_BIO_H + +#include "ace/pre.h" + +#include "SSL_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)) + +#include <openssl/bio.h> + +/** + * @name OpenSSL BIO Helper Methods for use with ACE's Asynchronous + * SSL I/O support. + */ +//@{ +extern "C" +{ + int ACE_Asynch_BIO_write (BIO *pBIO, const char *buf, int len); + int ACE_Asynch_BIO_read (BIO *pBIO, char *buf, int len); + int ACE_Asynch_BIO_puts (BIO *pBIO, const char *str); + long ACE_Asynch_BIO_ctrl (BIO *pBIO, int cmd, long arg1, void *arg2); + int ACE_Asynch_BIO_new (BIO *pBIO); + int ACE_Asynch_BIO_free (BIO *pBIO); +} +//@} + +#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */ + +#include "ace/post.h" + +#endif /* ACE_SSL_ASYNCH_BIO_H */ diff --git a/ace/SSL/SSL_Asynch_Stream.cpp b/ace/SSL/SSL_Asynch_Stream.cpp new file mode 100644 index 00000000000..1db55e9e429 --- /dev/null +++ b/ace/SSL/SSL_Asynch_Stream.cpp @@ -0,0 +1,1110 @@ +// -*- C++ -*- + +#include "SSL_Asynch_Stream.h" + +ACE_RCSID (ACE_SSL, + SSL_Asynch_Stream, + "$Id$") + +// This only works on platforms with Asynchronous IO support. +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)) + + +#if defined (ACE_WIN32) + +# define A_RESULT ACE_WIN32_Asynch_Result +# define ARS_RESULT ACE_WIN32_Asynch_Read_Stream_Result +# define AWS_RESULT ACE_WIN32_Asynch_Write_Stream_Result + +# define ERR_CANCELED ERROR_OPERATION_ABORTED + +# include "ace/WIN32_Proactor.h" + +#else + +# define A_RESULT ACE_POSIX_Asynch_Result +# define ARS_RESULT ACE_POSIX_Asynch_Read_Stream_Result +# define AWS_RESULT ACE_POSIX_Asynch_Write_Stream_Result + +# define ERR_CANCELED ECANCELED + +# include "ace/POSIX_Proactor.h" + +#endif /* ACE_WIN32 */ + +#include "ace/Proactor.h" + +// ************************************************************ +// SSL Asynchronous Write Result +// ************************************************************ + +class ACE_SSL_Export ACE_SSL_Asynch_Write_Stream_Result: + public AWS_RESULT +{ + /// Factory class will have special permissions. + friend class ACE_SSL_Asynch_Stream; + +protected: + + ACE_SSL_Asynch_Write_Stream_Result (ACE_Handler &handler, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + u_long bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number); +}; + +ACE_SSL_Asynch_Write_Stream_Result::ACE_SSL_Asynch_Write_Stream_Result + (ACE_Handler & handler, + ACE_HANDLE handle, + ACE_Message_Block & message_block, + u_long bytes_to_write, + const void * act, + ACE_HANDLE event, + int priority, + int signal_number + ) + : AWS_RESULT (handler, + handle, + message_block, + bytes_to_write, + act, + event, + priority, + signal_number + ) +{ +} + +// ************************************************************ +// SSL Asynchronous Read Result +// ************************************************************ +class ACE_SSL_Export ACE_SSL_Asynch_Read_Stream_Result: + public ARS_RESULT +{ + /// Factory class will have special permissions. + friend class ACE_SSL_Asynch_Stream; + +protected: + + ACE_SSL_Asynch_Read_Stream_Result (ACE_Handler &handler, + ACE_HANDLE handle, + ACE_Message_Block &message_block, + u_long bytes_to_read, + const void* act, + ACE_HANDLE event, + int priority, + int signal_number); +}; + + + +ACE_SSL_Asynch_Read_Stream_Result::ACE_SSL_Asynch_Read_Stream_Result + (ACE_Handler & handler, + ACE_HANDLE handle, + ACE_Message_Block & message_block, + u_long bytes_to_read, + const void * act, + ACE_HANDLE event, + int priority, + int signal_number + ) + : ARS_RESULT (handler, + handle, + message_block, + bytes_to_read, + act, + event, + priority, + signal_number + ) +{ +} + + +// ************************************************************ +// Faked Result. It is used for close notification +// ************************************************************ +class ACE_SSL_Asynch_Result : public A_RESULT +{ +public: + ACE_SSL_Asynch_Result (ACE_Handler & handler); + + void complete (u_long bytes_transferred, + int success, + const void * completion_key, + u_long error); +}; + +ACE_SSL_Asynch_Result::ACE_SSL_Asynch_Result + (ACE_Handler & handler) + : A_RESULT (handler, + 0, // act, + ACE_INVALID_HANDLE, + 0, // Offset + 0, // OffsetHigh + 0, // Priority + ACE_SIGRTMIN //signal_number + ) +{ +} + +void +ACE_SSL_Asynch_Result::complete (u_long /* bytes_transferred */, + int /* success */, + const void * /* completion_key */, + u_long /* error */) +{ + this->handler_.handle_wakeup (); +} + +// ************************************************************ +// ACE_SSL_Asynch_Stream Constructor / Desctructor +// ************************************************************ +ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream ( + ACE_SSL_Asynch_Stream::Stream_Type s_type, + ACE_SSL_Context * context) + : type_ (s_type), + handle_ (ACE_INVALID_HANDLE), + proactor_ (0), + ext_handler_ (0), + ext_read_result_ (0), + ext_write_result_(0), + flags_ (0), + ssl_ (0), + bio_ (0), + bio_istream_ (), + bio_inp_msg_ (), + bio_inp_errno_(0), + bio_inp_flag_ (0), + bio_ostream_ (), + bio_out_msg_ (), + bio_out_errno_(0), + bio_out_flag_ (0), + mutex_ () +{ + ACE_TRACE ("ACE_SSL_Asynch_Stream::ACE_SSL_Asynch_Stream"); + // was honestly copied from ACE_SSL_SOCK_Stream :) + + ACE_SSL_Context * ctx = + (context == 0 ? ACE_SSL_Context::instance () : context); + + this->ssl_ = ::SSL_new (ctx->context ()); + + if (this->ssl_ == 0) + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"), + ACE_TEXT ("- cannot allocate new SSL structure") + )); + + ::SSL_set_verify (this->ssl_, + ctx->default_verify_mode (), + 0); +} + +ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream (void) +{ + ACE_TRACE ("ACE_SSL_Asynch_Stream::~ACE_SSL_Asynch_Stream"); + + + // It is safe to delete stream if all notifications are received, + // i.e., state is SF_DELETE_ENABLE or if proactor event loop is + // done. + if (this->flags_ & SF_STREAM_OPEN) // open + if ((this->flags_ & SF_DELETE_ENABLE) == 0) // but .. + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("ACE_SSL_Asynch_Stream::DTOR-") + ACE_TEXT("possible access violation ") + ACE_TEXT("if proactor still handles events\n"))); + + ::SSL_free (this->ssl_); + this->ssl_ = 0; + + // Was honestly copied from ACE_SSL_SOCK_Stream :) + + // @@ Question: should we reference count the Context object or + // leave that to the application developer? We do not reference + // count reactors (for example) and following some simple rules + // seems to work fine! +} + +// ************************************************************ +// close () +// returns : +// 0 - Stream is in the state SF_DELETE_ENABLE, +// so it is safe to delete stream +// -1 - Stream has pending AIO requests, +// close should be repeated later one more +// ************************************************************ + +int +ACE_SSL_Asynch_Stream::close (void) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); + + if ((flags_ & SF_STREAM_OPEN) == 0) // not open + flags_ |= SF_DELETE_ENABLE; + + if (flags_ & SF_DELETE_ENABLE) + return 0; + + flags_ |= SF_REQ_SHUTDOWN; + + this->do_SSL_state_machine (); + + return -1; +} + +// ************************************************************ +// Asynch_Operation interface +// cancel +// ************************************************************ +int +ACE_SSL_Asynch_Stream::cancel (void) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); + + if ((flags_ & SF_STREAM_OPEN) == 0) // not open + return 1; // AIO_ALLDONE + + // attempt to cancel internal, i.e. user's read/write + int rc_r_int = bio_istream_.cancel(); + int rc_w_int = bio_ostream_.cancel(); + + // attempt to cancel external, i.e. bio_ssl read/write + int rc_r_ext = notify_read (0, ERR_CANCELED); + int rc_w_ext = notify_read (0, ERR_CANCELED); + + if (rc_r_int < 0 || rc_w_int < 0 + && rc_r_ext < 0 || rc_w_ext < 0) + return -1; // at least one error + + if (rc_r_int == 1 && rc_w_int == 1 + && rc_r_ext == 1 && rc_w_ext == 1) + return 1; // AIO_ALLDONE + + if (rc_r_int == 2 || rc_w_int == 2 + && rc_r_ext == 2 || rc_w_ext == 2) + return 2; // AIO_NOT_CANCELED , at least one not canceled + + return 0; // AIO_CANCELED, at least will be one notification +} + +// ************************************************************ +// Asynch_Operation interface +// open +// ************************************************************ +int +ACE_SSL_Asynch_Stream::open (ACE_Handler & handler, + ACE_HANDLE handle, + const void * completion_key, + ACE_Proactor * proactor) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); + + if (this->flags_ & SF_STREAM_OPEN) + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), + ACE_TEXT ("- already opened")), + -1); + + if (this->ssl_ == 0) + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), + ACE_TEXT ("- SSL structure is absent")), + -1); + + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), + ACE_TEXT ("- invalid handle")), + -1); + + + // Get a proactor for/from the user. + this->proactor_ = this->get_proactor (proactor, handler); + this->ext_handler_ = & handler; + this->handle_ = handle; + + // Open internal input stream + if (this->bio_istream_.open (*this, // real callbacks to this + handle, + completion_key, + this->proactor_) != 0) + return -1; + + // Open internal output stream + if (this->bio_ostream_.open (*this, // real callbacks to this + handle, + completion_key, + this->proactor_) != 0) + return -1; + + this->bio_ = ::BIO_new_ACE_Asynch (this); + + if (this->bio_ == 0) + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), + ACE_TEXT ("- cannot allocate new BIO structure")), + -1); + + ::SSL_set_bio (this->ssl_ , this->bio_ , this->bio_); + + switch (this->type_) + { + case ST_CLIENT: + ::SSL_set_connect_state (this->ssl_); + break; + + case ST_SERVER: + ::SSL_set_accept_state (this->ssl_); + break; + + default: + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream::open() %p\n"), + ACE_TEXT ("- invalid stream type")), + -1); + } + + this->flags_ |= SF_STREAM_OPEN; + + this->do_SSL_state_machine (); + + return 0; +} + +// ************************************************************ +// Asynch_Operation interface +// read +// ************************************************************ +int +ACE_SSL_Asynch_Stream::read (ACE_Message_Block & message_block, + u_long bytes_to_read, + const void * act, + int priority, + int signal_number) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); + + if ((this->flags_ & SF_STREAM_OPEN) == 0) // not open + return -1; + + if (this->flags_ & SF_REQ_SHUTDOWN) + return -1; + + // only one read operation is allowed now + // later it will be possible to make a queue + + if (this->ext_read_result_ != 0) + return -1; + + // create result for future notification + ACE_NEW_RETURN (this->ext_read_result_, + ACE_SSL_Asynch_Read_Stream_Result ( + *this->ext_handler_, + this->handle_, + message_block, + bytes_to_read, + act, + this->proactor_->get_handle(), + priority, + signal_number), + -1); + + this->do_SSL_state_machine (); // ignore return code + + return 0; +} + +// ************************************************************ +// Asynch_Operation interface +// write +// ************************************************************ +int +ACE_SSL_Asynch_Stream::write (ACE_Message_Block & message_block, + u_long bytes_to_write, + const void * act, + int priority, + int signal_number) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1)); + + if ((this->flags_ & SF_STREAM_OPEN) == 0) // not open + return -1; + + if (this->flags_ & SF_REQ_SHUTDOWN) + return -1; + + // only one read operation is allowed now + // later it will be possible to make a queue + + if (this->ext_write_result_ != 0) + return -1; + + // create result for future notification + ACE_NEW_RETURN (this->ext_write_result_, + ACE_SSL_Asynch_Write_Stream_Result ( + *this->ext_handler_, + this->handle_, + message_block, + bytes_to_write, + act, + this->proactor_->get_handle(), + priority, + signal_number), + -1); + + this->do_SSL_state_machine (); + + return 0; +} + +// ************************************************************ +// Main SSL engine +// ************************************************************ +int +ACE_SSL_Asynch_Stream::do_SSL_state_machine (void) +{ + // this protected member should be called + // with locked mutex_ + + int retval = this->do_SSL_handshake (); + + if (retval == 0) // handshake in progress ? + return 0; + + if (retval < 0) + this->flags_ |= SF_REQ_SHUTDOWN; + + this->do_SSL_read (); // execute user read request + this->do_SSL_write (); // execute user write request + + if ((this->flags_ & SF_REQ_SHUTDOWN) == 0) // Do we have any errors + return 0; + + this->do_SSL_shutdown (); + + this->notify_close (); + + return 0; +} + +// ************************************************************ +// do_SSL_shutdown +// return code: +// 1 SSL shutdown is finished already, success +// 0 SSL shutdown in progress +// -1 failure +// ************************************************************ +int +ACE_SSL_Asynch_Stream::do_SSL_shutdown (void) +{ + if (this->flags_ & SF_SHUTDOWN_DONE) // already done + return 1; + + this->flags_ |= SF_REQ_SHUTDOWN; + + // if we have any uncompleted user requests + // than cancel its + this->notify_read (0, ERR_CANCELED); + this->notify_write (0, ERR_CANCELED); + + int retval = ::SSL_shutdown (this->ssl_); + + int status = ::SSL_get_error (this->ssl_, retval); + + switch (status) + { + case SSL_ERROR_NONE: + case SSL_ERROR_ZERO_RETURN: + case SSL_ERROR_SYSCALL: + retval = 1; + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_CONNECT: + // case SSL_ERROR_WANT_ACCEPT: + case SSL_ERROR_WANT_X509_LOOKUP: + return 0; + + default: + this->print_error (status, + ACE_TEXT ("Shutdown error")); + retval = -1; + break; + } + + this->flags_ |= SF_SHUTDOWN_DONE; + + return -1; +} + +// ************************************************************ +// Do SSL handshake if necessary +// return code: +// 1 SSL handshake is finished already, success +// 0 SSL handshake in progress +// -1 failure +// ************************************************************ +int +ACE_SSL_Asynch_Stream::do_SSL_handshake (void) +{ + if (SSL_is_init_finished (this->ssl_)) + return 1; + + if (this->flags_ & SF_REQ_SHUTDOWN) + return -1; + + int retval = -1; + + switch (this->type_) + { + case ST_CLIENT: + retval = ::SSL_connect (this->ssl_); + break; + + case ST_SERVER: + retval = ::SSL_accept (this->ssl_); + break; + + default: + ACE_ERROR_RETURN + ((LM_ERROR, + ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"), + ACE_TEXT ("- invalid stream type")), + -1); + } + + int status = ::SSL_get_error (this->ssl_, retval); + + switch (status) + { + case SSL_ERROR_NONE: + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_CONNECT: + //case SSL_ERROR_WANT_ACCEPT: + case SSL_ERROR_WANT_X509_LOOKUP: + return 0; + + case SSL_ERROR_ZERO_RETURN: + case SSL_ERROR_SYSCALL: + default: + this->print_error (status, + ACE_TEXT ("Handshake error")); + return -1; + } + + return 1; +} + +// ************************************************************ +// Perform SSL_read call if necessary and notify user +// ************************************************************ +int +ACE_SSL_Asynch_Stream::do_SSL_read (void) +{ + if (this->ext_read_result_ == 0) // nothing to do + return 0; + + if (this->flags_ & SF_REQ_SHUTDOWN) + { + this->notify_read (0, ERR_CANCELED); + return -1; + } + + ACE_Message_Block & mb = this->ext_read_result_->message_block (); + u_long bytes_req = this->ext_read_result_->bytes_to_read (); + + int bytes_trn = ::SSL_read (this->ssl_, + mb.rd_ptr (), + bytes_req); + + int status = ::SSL_get_error (this->ssl_, bytes_trn); + + switch (status) + { + case SSL_ERROR_NONE: + this->notify_read (bytes_trn, 0); + return 1; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + return 0; + + case SSL_ERROR_ZERO_RETURN: + this->notify_read (0, 0); + return 1; + + case SSL_ERROR_SYSCALL: + if (bytes_trn == 0) + { + this->notify_read (0, 0); + return 1; + } + // If not an EOF, then fall through to "default" case. + + default: + break; + } + + this->notify_read (0, EFAULT); + this->print_error (status, + ACE_TEXT ("SSL_read error")); + + return -1; +} + +// ************************************************************ +// Perform SSL_write call if necessary and notify user +// ************************************************************ +int +ACE_SSL_Asynch_Stream::do_SSL_write (void) +{ + if (this->ext_write_result_ == 0) // nothing to do + return 0; + + if (this->flags_ & SF_REQ_SHUTDOWN) + { + this->notify_write (0, ERR_CANCELED); + return -1; + } + + ACE_Message_Block & mb = this->ext_write_result_->message_block (); + u_long bytes_req = this->ext_write_result_->bytes_to_write (); + + int bytes_trn = ::SSL_write (this->ssl_, + mb.rd_ptr (), + bytes_req); + + int status = ::SSL_get_error (this->ssl_, bytes_trn); + + switch (status) + { + case SSL_ERROR_NONE: + this->notify_write (bytes_trn, 0); + return 1; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + return 0; + + case SSL_ERROR_ZERO_RETURN: + this->notify_write (bytes_trn, 0); + return 1; + + case SSL_ERROR_SYSCALL: + default: + break; + } + + this->notify_write(0, EFAULT); + this->print_error (status, + ACE_TEXT ("SSL_write error")); + + return -1; +} + +// ************************************************************ +// notify external user handler that +// it is now to safe destroy stream +// Return code looks like cancel() return code +// 0 - notified NOTIFIED +// 1 - nothing to notify ALLDONE +// 2 - unable to notify NOT NOTIFIED +// ************************************************************ +int +ACE_SSL_Asynch_Stream::notify_close (void) +{ + if (this->flags_ & SF_CLOSE_NTF_SENT) // already sent + return 1; + + if ((this->flags_ & SF_SHUTDOWN_DONE) == 0) // only after shutdown + return 2; // too early , we will do later + + if (this->pending_BIO_count () != 0) // wait for all internal IO + return 2; // too early , we will do later + + // create result for future notification + ACE_SSL_Asynch_Result * close_result = 0; + + ACE_NEW_RETURN (close_result, + ACE_SSL_Asynch_Result (*this), + 2); + //@@ Not exception safe! + + int retval = + close_result->post_completion (this->proactor_->implementation ()); + + if (retval == 0) + { + this->flags_ |= SF_CLOSE_NTF_SENT; + return 0; + } + + delete close_result; + return 2; +} + +// ************************************************************ +// notify external user handler about user write completion +// Return code looks like cancel() return code +// 0 - notified NOTIFIED/CANCELED +// 1 - nothing to notify ALLDONE +// 2 - unable to notify NOT NOTIFIED/CANCELED +// ************************************************************ + +int +ACE_SSL_Asynch_Stream::notify_read (int bytes_transferred, + int error) +{ + if (ext_read_result_ == 0) //nothing to notify + return 1; + + ext_read_result_->set_bytes_transferred (bytes_transferred); + ext_read_result_->set_error (error); + + int retval = ext_read_result_->post_completion + (proactor_->implementation()); + + if (retval == 0) + { + ext_read_result_ = 0; + return 0; // success + } + + return 2; // unable to notify +} + +// ************************************************************ +// notify external user handler about user write completion +// Return code looks like cancel() return code +// 0 - notified NOTIFIED/CANCELED +// 1 - nothing to notify ALLDONE +// 2 - unable to notify NOT NOTIFIED/CANCELED +// ************************************************************ + +int +ACE_SSL_Asynch_Stream::notify_write (int bytes_transferred, + int error) +{ + if (this->ext_write_result_ == 0) //nothing to notify + return 1; + + this->ext_write_result_->set_bytes_transferred (bytes_transferred); + this->ext_write_result_->set_error (error); + + int retval = + this->ext_write_result_->post_completion ( + this->proactor_->implementation ()); + + if (retval == 0) + { + this->ext_write_result_ = 0; + return 0; // success + } + + return 2; // unable to notify +} + +// ************************************************************ +// Print SSL errors +// ************************************************************ +void +ACE_SSL_Asynch_Stream::print_error (int err_ssl, + const ACE_TCHAR * pText) +{ + ACE_DEBUG ((LM_DEBUG, + "SSL-error:%d %s\n" , + err_ssl, + pText)); + + unsigned long lerr = 0; + char buf[1024]; + + while ((lerr = ERR_get_error()) != 0) + { + ERR_error_string_n (lerr, buf, sizeof buf); + + ACE_DEBUG ((LM_DEBUG, "%s\n", buf)); + } +} + +// ************************************************************ +// BIO helper functions +// SSL library will ask BIO to do raw I/O +// BIO will call us to do this +// ************************************************************ +int +ACE_SSL_Asynch_Stream::ssl_bio_read (char * buf, + size_t len, + int & errval) +{ + // We do not have to acquire mutex + // as we called already with locked mutex + // from do_SSL_state_machine() + + errval = 0; + + size_t cur_len = this->bio_inp_msg_.length (); + + if (cur_len > 0) // there are more data buffered + { + const char * rd_ptr = this->bio_inp_msg_.rd_ptr (); + + if (cur_len > len) + cur_len = len; + + ACE_OS::memcpy (buf, rd_ptr, cur_len); + + this->bio_inp_msg_.rd_ptr (cur_len); // go ahead + + return cur_len; + } + + if (this->bio_inp_errno_ != 0) // if was error - it is permanent ! + { + errval = this->bio_inp_errno_; + return -1; + } + + if (this->bio_inp_flag_ & BF_EOS) // End of stream + return 0; + + errval = EINPROGRESS; // SSL will try later + + if (this->bio_inp_flag_ & BF_AIO) // we are busy + return -1; + + if (this->bio_inp_msg_.size (len) != 0) + { + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"), + ACE_TEXT ("error in ACE_Message_Block::size() ") + )); + + errval = EINVAL; + return -1; + } + + char * base = this->bio_inp_msg_.base (); + + this->bio_inp_msg_.rd_ptr (base); + this->bio_inp_msg_.wr_ptr (base); + + if (this->bio_istream_.read ( + bio_inp_msg_, // message block + len, // priority + 0, // act + 0, // priority + ACE_SIGRTMIN // default signal + ) == -1) + { + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("%N:%l (%P|%t) ACE_SSL_Asynch_Stream %p\n"), + ACE_TEXT ("attempt read failed") + )); + + errval = EINVAL; // may be leave EINPROGRESS ?? + return -1; // to try later + } + + this->bio_inp_flag_ |= BF_AIO; // AIO is active + + return -1; +} + + +int +ACE_SSL_Asynch_Stream::ssl_bio_write (const char * buf, + size_t len, + int & errval) +{ + // We do not have to acquire mutex + // as we called already with locked mutex + // from do_SSL_state_machine + + errval = 0; + + if (this->bio_out_flag_ & BF_AIO) // sorry, we are busy + { + errval = EINPROGRESS; // try later + return -1; + } + + if (this->bio_out_errno_ != 0) // no recovery + { + errval = this->bio_out_errno_; + return -1; + } + + if (this->bio_out_msg_.size (len) != 0) + { + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"), + ACE_TEXT ("error in ACE_Message_Block::size() ") + )); + + errval = EINVAL; + return -1; + } + + char * base = this->bio_out_msg_.base (); + + this->bio_out_msg_.rd_ptr (base); + this->bio_out_msg_.wr_ptr (base); + + if (this->bio_out_msg_.copy (buf, len) == -1) + { + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"), + ACE_TEXT ("error in ACE_Message_Block::copy() ") + )); + + errval = EINVAL; + return -1; + } + + + if (this->bio_ostream_.write ( + this->bio_out_msg_, // message block + len, // priority + 0, // act + 0, // priority + ACE_SIGRTMIN // default signal + ) == -1) + { + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("%N:%l ((%P|%t) ACE_SSL_Asynch_Stream %p\n"), + ACE_TEXT ("attempt write failed") + )); + + errval = EINVAL; // may be leave EINPROGRESS ?? + return -1; // to try later + } + + this->bio_out_flag_ |= BF_AIO; // AIO is active + errval = 0; // Ok, go ahead + + return len; +} + +// ************************************************************ +// Internal IO handlers +// virtual from ACE_Service_Handler +// ************************************************************ +void +ACE_SSL_Asynch_Stream::handle_write_stream ( + const ACE_Asynch_Write_Stream::Result &result) +{ + ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_)); + + this->bio_out_flag_ &= ~BF_AIO; + + ACE_Message_Block & mb = result.message_block (); + + u_long bytes_req = result.bytes_to_write (); + u_long bytes_trn = result.bytes_transferred (); + u_long errval = result.error (); + size_t len = bytes_req - bytes_trn; + + if (errval != 0) // error ? + this->bio_out_errno_ = errval; // save error code + else if (len > 0) // TCP/IP overloaded ? + { // continue, rd_ptr at right place + if (this->bio_ostream_.write ( + mb, // message block + len, // priority + 0, // act + 0, // priority + ACE_SIGRTMIN // default signal + ) == 0) + { + this->bio_out_flag_ |= BF_AIO; + return; + } + + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"), + ACE_TEXT ("attempt write failed") + )); + + this->bio_out_errno_ = EINVAL; + } + + this->do_SSL_state_machine (); + + return; +} + +void +ACE_SSL_Asynch_Stream::handle_read_stream ( + const ACE_Asynch_Read_Stream::Result &result) +{ + ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_)); + + this->bio_inp_flag_ &= ~BF_AIO; + + u_long bytes_trn = result.bytes_transferred (); + u_long errval = result.error (); + + if (errval != 0) // error ? + this->bio_inp_errno_ = errval; // save error code + else if (bytes_trn == 0) // end of stream ? + this->bio_inp_flag_ |= BF_EOS; // set flag EOS + + this->do_SSL_state_machine (); + + return; +} + +void +ACE_SSL_Asynch_Stream::handle_wakeup (void) +{ + ACE_Handler * user_handler = 0; + + { + ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->mutex_)); + + this->flags_ |= SF_DELETE_ENABLE; + + user_handler = this->ext_handler_; + } + + if (user_handler != 0) + user_handler->handle_wakeup(); +} + +int +ACE_SSL_Asynch_Stream::pending_BIO_count (void) +{ + int ret = 0; + + if (this->bio_inp_flag_ & BF_AIO) + ret++; + + if (this->bio_out_flag_ & BF_AIO) + return ret++; + + return ret; +} + +#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */ diff --git a/ace/SSL/SSL_Asynch_Stream.h b/ace/SSL/SSL_Asynch_Stream.h new file mode 100644 index 00000000000..753998e0cb8 --- /dev/null +++ b/ace/SSL/SSL_Asynch_Stream.h @@ -0,0 +1,236 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file SSL_Asynch_Stream.h + * + * $Id$ + * + * @author Alexander Libman <alibman@baltimore.com> + * + */ +//============================================================================= + +#ifndef ACE_SSL_ASYNCH_STREAM_H +#define ACE_SSL_ASYNCH_STREAM_H + +#include "ace/pre.h" +#include "SSL_Context.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)) + +#include <openssl/err.h> + +#include "ace/Asynch_IO_Impl.h" +#include "ace/Message_Block.h" + +#include "SSL_Asynch_BIO.h" + +extern "C" +{ + BIO_METHOD * BIO_s_ACE_Asynch (void); + BIO * BIO_new_ACE_Asynch (void *ssl_asynch_stream); +} + + +/// Forward declarations +class ACE_SSL_Asynch_Stream; +class ACE_SSL_Asynch_Result; +class ACE_SSL_Export ACE_SSL_Asynch_Read_Stream_Result; +class ACE_SSL_Export ACE_SSL_Asynch_Write_Stream_Result; + + +/** + * @class ACE_SSL_Asynch_Stream + * + * @brief This class is a factory for starting off asynchronous reads + * on a stream. This class forwards all methods to its + * implementation class. + * @par + * Once open() is called, multiple asynchronous read()s can + * started using this class. An ACE_SSL_Asynch_Stream::Result + * will be passed back to the @param handler when the asynchronous + * reads completes through the ACE_Handler::handle_read_stream + * callback. + */ +class ACE_SSL_Export ACE_SSL_Asynch_Stream + : public ACE_Asynch_Operation, + public ACE_Service_Handler +{ + friend int ACE_Asynch_BIO_read (BIO * pBIO, char * buf, int len); + friend int ACE_Asynch_BIO_write (BIO * pBIO, const char * buf, int len); + +public: + + enum Stream_Type + { + ST_CLIENT = 0x0001, + ST_SERVER = 0x0002 + }; + + + /// The constructor. + ACE_SSL_Asynch_Stream (Stream_Type s_type = ST_SERVER, + ACE_SSL_Context * context = 0); + + /// Destructor + virtual ~ACE_SSL_Asynch_Stream (void); + + int cancel(void); + + int close (void); + + int open (ACE_Handler &handler, + ACE_HANDLE handle = ACE_INVALID_HANDLE, + const void *completion_key = 0, + ACE_Proactor *proactor = 0); + + int read (ACE_Message_Block &message_block, + u_long num_bytes_to_read, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + + int write (ACE_Message_Block &message_block, + u_long bytes_to_write, + const void *act = 0, + int priority = 0, + int signal_number = ACE_SIGRTMIN); + +protected: + + /// virtual from ACE_Service_Handler + + /// This method is called when BIO write request is completed. It + /// processes the IO completion and calls do_SSL_state_machine(). + virtual void handle_write_stream + (const ACE_Asynch_Write_Stream::Result &result); + + /// This method is called when BIO read request is completed. It + /// processes the IO completion and calls do_SSL_state_machine(). + virtual void handle_read_stream + (const ACE_Asynch_Read_Stream::Result &result); + + /// This method is called when all SSL sessions are closed and no + /// more pending AIOs exist. It also calls users handle_wakeup(). + virtual void handle_wakeup (void); + + /** + * @name SSL State Machine + */ + //@{ + int do_SSL_state_machine (void); + int do_SSL_handshake (void); + int do_SSL_read (void); + int do_SSL_write(void); + int do_SSL_shutdown(void); + //@} + + void print_error (int err_ssl, + const ACE_TCHAR *pText); + + int pending_BIO_count (void); + + /// This method is called to notify user handler when user's read in + /// done. + int notify_read (int bytes_transferred, int error); + + /// This method is called to notify user handler when user's write + /// in done. + int notify_write (int bytes_transferred, int error); + + /// This method is called to notify ourself that SSL session is + /// shutdown and that there is no more I/O activity now and in the + /// future. + int notify_close(void); + + /** + * @name BIO Helpers + */ + //@{ + int ssl_bio_read (char * buf, size_t len, int & errval); + int ssl_bio_write (const char * buf, size_t len, int & errval); + //@} + +protected: + + /// Stream Type ST_CLIENT/ST_SERVER + Stream_Type type_; + + /// The real file/socket handle + ACE_HANDLE handle_; + + /// The proactor + ACE_Proactor * proactor_; + + /// External,i.e user handler + ACE_Handler * ext_handler_; + + /// External, i.e. read result faked for user + ACE_SSL_Asynch_Read_Stream_Result * ext_read_result_ ; + + /// External, i.e. write result faked for user + ACE_SSL_Asynch_Write_Stream_Result * ext_write_result_ ; + + /// Stream state/flags + enum Stream_Flag + { + SF_STREAM_OPEN = 0x0001, /// istream_ open OK + SF_REQ_SHUTDOWN = 0x0002, /// request to SSL shutdown + SF_SHUTDOWN_DONE = 0x0004, /// SSL shutdown finished + SF_CLOSE_NTF_SENT = 0x0008, /// Close notification sent + SF_DELETE_ENABLE = 0x0010 /// Stream can be safely destroyed + }; + + int flags_; + + /// The SSL session. + SSL * ssl_; + + /// The BIO implementation + BIO * bio_; + + /// The real streams which work under the ssl connection. + /// BIO performs I/O via this streams + + enum BIO_Flag // internal IO flags + { + BF_EOS = 0x01, // end of stream + BF_AIO = 0x02 // real AIO in progress + }; + + /** + * @name Internal stream, buffer and info for BIO read + */ + //@{ + ACE_Asynch_Read_Stream bio_istream_; + ACE_Message_Block bio_inp_msg_; + int bio_inp_errno_; + int bio_inp_flag_; + //@} + + /** + * @name Internal stream, buffer and info for BIO write + */ + //@{ + ACE_Asynch_Write_Stream bio_ostream_; + ACE_Message_Block bio_out_msg_; + int bio_out_errno_; + int bio_out_flag_; + //@} + + /// Mutex to protect work + ACE_SYNCH_MUTEX mutex_; + +}; + + +#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */ + +#include "ace/post.h" + +#endif /* ACE_SSL_ASYNCH_STREAM_H */ |