Combined replies. > Maybe we should look on other papers, for example part of select(2) > man page from hpux 11.23: > > Ttys and sockets are ready for reading or writing, respectively, if a > read() or write() would not block for one or more of the following > reasons: > + input data is available. > + output data can be accepted. > + an error condition exists, such as a broken pipe, > no carrier, or a lost connection. > > More, this statement already exists in hpux 10.0 (documentation > from 1995).
Yes, I agree with this. As I said, 'select' should indicate a 'read' hit if at some point in between when you called 'select' and when it returned, a 'read' would not have blocked. Notice this says nothing about any *future* operations. > And of course this may change if two threads will use in parallel > one socket in the Bermuda Triangle, but this is not that case. This does not provide any future guarantees. It says a socket is ready for reading if a read will not block, but it doesn't say that once a socket is ready for reading it must remain so until any particular time. Note also that this says it wouldn't block for specific reasons. This strongly suggests that it *could* block for other reasons not listed. So actually it's hard to imagine what the list is for if not to caution you that a subsequent operation *can* block. For example, one of the cases where code making this assumption actually broke was Linux code that used 'select' followed by 'read' on UDP sockets. Surprise, the 'read' call blocked for a reason not listed that nobody at the time realized wasn't listed -- the checksum on the packet was bad. Input data was available, but it didn't satisfy the 'read' request (because 'read' implicitly asks for *valid* data only). The guarantee you want does not exist. You cannot produce it. You do not have it. Really, it's as simple as that. > And of course this may change if two threads will use in parallel > one socket in the Bermuda Triangle, but this is not that case. This would be a valid argument if the standard didn't specifically provide us a way to get the exact guarantee you want. It's this simple: 1) You need a particular guarantee, specifically, that a 'read' won't block. 2) The standard provides you a clear way to get that guarantee, by setting the socket non-blocking. 3) You can't think of any way for the 'read' to block, but you are not guaranteed it. How hard is that to follow? --- From Windows documentation: > For other sockets, readability means that queued data is available > for reading such that a call to recv, WSARecv, WSARecvFrom, > or recvfrom is guaranteed not to block. That's not a standard, so it applies to Windows only. Also, it does not specify *what* call to WSARecv is guaranteed not to block or how you can tell which of those functions the guarantee applies to. Unlike POSIX, at least the intention was there to provide this guarantee on Windows. --- >I call again for David to prove an existing implementation of >poll/select which does not confirm to the above guarantees. David is >claiming that: That is not how you code to standards. You don't give a fig what existing implementation do, you care about what gurantees you have. In any event, a platform the spliced 'select'/'read'/'write' to OpenSSL is an existing implementation that does not provide these guarantees. >* A readability event can disappear (after it has been first indicated >by poll/select and no read() family of functions have been called, >recvmsg()/recv() etc... >* A writability event can disappear (after it has been first indicated >by poll/select and no write() family of functions have been called, >sendmsg()/send() etc... Yep, and that's exactly what happened IN THIS VERY CASE WE ARE ALL TALKING ABOUT. You got a 'select' hit because there was data, but then 'read' blocked because the data was not application data. I'm not claiming it happened, it happened. That's why we're having this thread. >The specifications for poll/select dont talk in terms of "nonblocking" >or "blocking" of other system call because that does not concern the >select system call. What does concern the select is the "readability" >and "writability" of the file descriptor. >What this meant by those terms is that the file descriptor "can do more >work" during the next syscall call related to it. This can also mean >partial writes are possible, or error return would be indicated, or >indicated end-of-stream. This can be through about as there is more >information the kernel has to convey to the application about that file >descriptor and kernel is ready to tell the application. Bingo! And work may or may not translate into application data. >Then by virtue of that fact the next read() or write() related call does >not block because we know there is something to do, even when the file >descriptor is in blocking mode (as per fcntl(fd, F_SETFL, 0);) This assumes that "something to do" *must* be the reading or writing of application data. As this thread proves, there can be other things to do. >In my wisdom of having written IO layers before in order to keep event >notification characteristics your first low-level call you make (per >high level invocation) you treat it will may block. Any futher low >level calls you want to make you must do so non-blocking or return -1 >WANT_READ/WANT_WRITE. What hypocrisy! You claim your goal is to make OpenSSL behave the same as the underlying I/O functions. The underlying I/O functions block until application data is available. That was what *I* argued OpenSSL should do. >The standards have to speak in terms of the entire scope of the subject. >The subject is the select() system all. So the select() standards have >to take into account other file descriptor contexts that are not socket >related and still be factually correct. This is why terms readable and >writable are used. You then have to relate that to a socket file >descriptor. In other words, the standards do not provide a guarantee that a blocking socket operation will not block. If they do, please show it to me. >A SSL_read() may infact issue a write() system call. Trying to tar the >whole situation with the same brush is an incorrect belief. The SSL is >another layer with its own wants and wishes, it does not conform to a >simple data transform that can be driven by IO in one direction. You have no way of knowing what layers the kernel may interpose between your socket operations and the network interface. The instant case demonstrates that the assumption you suggest *breaks* in the face of more complex underlying I/O. >Blocking mode of the higher level API calls is not interchangable with >the blocking mode of the lower level system calls. But if you execute >one system call per SSL level call they _DO_ become interchargable and >transparent. Nonsense. That is what *I* am arguing for. A blocking 'read' blocks until some application data can be read. Are you suggesting that is what SSL_read should do? *no*. So you are not making them interchangeable or transparent. I am suggesting they behave precisely the same way. A blocking read blocks until application data can be read, you must only call when you wish to block until application data can be read. I am suggesting SSL_read do the same thing. A blocking write blocks until at least some application data can be written, you must only call it when you wish to block until some application data can be queued. I am suggesting SSL_write do the same thing. *You* are suggesting a semantic difference. You want SSL_read to return even if it can't read any application data when the application specifically requested blocking semantics. Your justification is that if you don't do this, a guarantee that you don't actually have won't be kept. My response is, the fact that this perfectly legal code violates the guarantee you thought you had proves that you didn't have the guarantee. DS ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]