This mail is addressed to Dr Stephen N. Henson in connection with his previous 
post.


> I have never come across a report of a deadlock in that situation and several
> applications have reported using WSAEventSelect() in the past. There are
> several possible reasons...
>


There is very,very little chance the application to deadlock. 'send' command 
fails very rare. I have made a test - I've sent about 100 Mb at one time using 
nonblocking socket and windows consumed whole buffer at one time and 
immediately returned without  any error and with 100 Mb send (the data wasn't 
send of course) - it means that it has large enough buffer to consume big 
amount of data. I'm using windows xp, i don't know how it works on older 
systems (NT,98,me) maybe there is bigger probability to 'send' failure.  That's 
not all, i'm coding simple jabber client (i hope you know what is jabber). I've 
downloaded source code for one of the freeware clients recommended by main 
jabber.org site (by the way, this client is recommended at first place as 
windows client). I've looked at source and it seems that it uses openSSL 
improperly - in winsock fashion (which is good for unencrypted connection - it 
depends on jabber server),using 2 thread one for reading and one for writing, 
without any openSSL command serialization. (This is my opinion, maybe i've 
missed something but i don't think so, it's written in delphi and it uses indy 
components) But even using this rather improper for openSSL style, it seems 
that it doesn't cause much trouble. Probability of reading and writing exactly 
at the same time for communicator application is rather small, additionally 
scheduler must switch the threads in special moment of their work to cause race 
condition. So, deadlocks for most application are very rare and it is rather 
matter of correctness then real problem in real applications causes me to find 
proper way of implementing OpenSSL app.

> 1. The application works because of the feature mentioned in KB186245.
> 

I'm using XP

> 2. The send() function never returns any of the other BIO_sock_non_fatal_error
> codes so this is not an issue in practice. The documentation seems to suggest
> this but that's no guarantee.
> 

Well, that's the problem. I have no certainty that this is true and it will be 
true for further openSSL implementations, so i have to develop code to deal 
with it.


> Call select() with a zero second timeout. If it indicates socket is
> writable retry the opertion, if not call WSAEventSelect().


Theoretically this should be true since if openSSL returns error WANT_WRITE and 
it is not caused by WSAEWOULBLOCK (FD_WRITE event won't be send) it means that 
operation should just be immediatelly repeated and 'select' can be used to 
check this situation. But very theoretically i some case WANT_WRITE will not be 
send since windows can't check when writing will be possible. Windows signals 
this returning error other then WSAEWOULDBLOCK and some other checking method 
should be used, for example: repeated socket polling ('select' with timeout > 
0).(I hope you know what i mean) I know this is very abstract case, but it 
should reminded that OS API is something what is developed by many years for 
different OS versions, sometimes API is imported for compatibility from 
diffrent OSes, etc. So using only good sense is not reliable way to success. 
(for example why 'select' doesn't support socket and pipes at the same time? 
Won't it be better then implementing WSAXXX framework?). The only reliable way 
is to implement excactly with OS API specyfication.

> 
> Call WSAGetLastError() to confirm the error code.
> 

Yes,i have seen this method in some thread of this mailing list, but i think 
that it's not reliable method. I have no certainty that OpenSSL doesn't reset 
error code or some other windows command is not invoked after 'send' failure.

> 
> One is to write a custom socket BIO. In this case it would be very simple
> because it would copy all the existing methods *except* the write behaviour
> which would set the retry flag only if the error is WSAEWOULDBLOCK.
>

Unfortunately i'm using Delphi and openSSL is written in c, so it's not such 
easy for me.

 
> The second alternative is BIO pairs this give an application total flexibility
> on all socket I/O but is more complex to handle.
> 

Yes, much more.


I've developed some method, but i has limited usage, it can be used for some 
special kind of applications using one socket for reading and writing. (but 
this is exactly my case) Application must wait for 3 events: reading event,user 
event(used to tell that user want write) and write event(used only if 
WANT_WRITE occured). This trick is tightly connected with application 
logic.When app starts it waits for 2 events: FD_READ event and user event, it 
does it using 'WaitForMultipleObjects' command. It uses this construction all 
time till WANT_WRITE error will occur, then it can switch to loop which uses 
'select' statement as blocking function - the trick is very simple, when app 
can't write it doesn't have to wait for user event,
so 'select' statement can be used. When 'select' returns ability to write app 
can again switch to 'WaitForMultipleObjects' and so on. Do you ever came across 
this implementation? What do you think abou it? Have i missed something?  

 
I have one question to you, yet. If SSL_write blocks with WANT_WRITE error, 
theoretically i can still use SSL_read ? (I think i can). But what to do when 
SSL_read will return WANT_WRITE error? Which command i should repeat first? 
SSL_read, SSL_write or it doesn't metter?

Lucas

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to