× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.

Correct, that's not going to work.

The reason is that the GSKit routines will sometimes need some of the crypto data used in TLS/SSL to be sent over the network.  So select() will return that the socket is readable, but gsk_secure_soc_read() will not return any data -- it doesn't return any data because the data was used internally for TLS/SSL.

In a blocking socket, that means that gsk_secure_soc_read() will block.

In a non-blocking scenario, it means that gsk_secure_soc_read() will return 0 bytes.  And you can potentially call select() -- or poll() which does the same thing -- many times and and still get 0 bytes.

The best solution I've found is to use blocking sockets, and set timeouts instead of using select() or poll().

For example, prior to calling gsk_secure_soc_init, do something like this:

  rc = gsk_attribute_set_numeric_value(gskSoc, GSK_HANDSHAKE_TIMEOUT, timeOut / 1000);
  rc = gsk_attribute_set_numeric_value(gskSoc, GSK_IBMI_READ_TIMEOUT, timeOut);

(and check 'rc' for error, etc, as you normally would with GSkit.)

Notice that the handshake timeout is in seconds, whereas the read timeout is in milliseconds...  Easily fixed, but...  can lead to weird results if you don't notice it, lol.


On 2/13/2024 1:48 PM, Kelly Beard wrote:
I've done some socket programming in my past, and select() has been my
go-to to prevent hanging reads. Something isn't working in this case.
We've purposely asked the vendor we're sending to to not send a response in
order to test our timeout code. That appears to be working, at least on
their end. My tried-and-true method of ensuring that I don't hang on a
read when there is nothing there, is not. Below is what I have going on.
In essence, select() is returning right away with 1 as though there is
something available, but soc_read() hangs forever until something happens
(several minutes) and the read is terminated.

So, has anyone seen something like this before? Is there another method I
can use?

int amtRead = 0, totalRead = 0, select_rc;
fd_set read_set, write_set, error_set;
struct timeval timeout = { 10, 0 }; // 10 second timeout
FD_SET(sd, &read_set);
FD_SET(sd, &error_set);
timeout.tv_sec = TV_SEC; // reset this on every new iteration.
timeout.tv_usec = 0;

do {
if (bDebug) {
CERR2 << "calling select()...\n";
select_rc = select(sd + 1, &read_set, NULL, &error_set, &timeout);
if (bDebug) {
CERR << "select_rc=" << select_rc << '\n';

if (select_rc == 0) { // TIMEOUT
else if (select_rc == 1 && FD_ISSET(sd, &read_set)) {
timeout.tv_sec = 0;
timeout.tv_usec = 500000;

//Read via TLS
rc = gsk_secure_soc_read(my_session_handle, buff2,
sizeof(buff2), &amtRead);
if (rc != GSK_OK) {
sstr << "gsk_secure_soc_write() failed with rc = " << rc <<
" (" << gsk_strerror(rc) << "), errno=" << strerror(errno);
throw runtime_error(sstr.str());
// keep an accumualtor going
totalRead += amtRead;

code continues...

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.