if (r < num)
if (r < (int)num)
int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,	clock_t *s_time, clock_t *c_time)	{	long cw_num = count, cr_num = count, sw_num = count, sr_num = count;	BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;	BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;	int ret = 1;		size_t bufsiz = 256; /* small buffer for testing */	if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))		goto err;	if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))		goto err;		s_ssl_bio = BIO_new(BIO_f_ssl());	if (!s_ssl_bio)		goto err;	c_ssl_bio = BIO_new(BIO_f_ssl());	if (!c_ssl_bio)		goto err;	SSL_set_connect_state(c_ssl);	SSL_set_bio(c_ssl, client, client);	(void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);	SSL_set_accept_state(s_ssl);	SSL_set_bio(s_ssl, server, server);	(void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);	do		{		/* c_ssl_bio:          SSL filter BIO		 *		 * client:             pseudo-I/O for SSL library		 *		 * client_io:          client's SSL communication; usually to be		 *                     relayed over some I/O facility, but in this		 *                     test program, we're the server, too:		 *		 * server_io:          server's SSL communication		 *		 * server:             pseudo-I/O for SSL library		 *		 * s_ssl_bio:          SSL filter BIO		 *		 * The client and the server each employ a "BIO pair":		 * client + client_io, server + server_io.		 * BIO pairs are symmetric.  A BIO pair behaves similar		 * to a non-blocking socketpair (but both endpoints must		 * be handled by the same thread).		 * [Here we could connect client and server to the ends		 * of a single BIO pair, but then this code would be less		 * suitable as an example for BIO pairs in general.]		 *		 * Useful functions for querying the state of BIO pair endpoints:		 *		 * BIO_ctrl_pending(bio)              number of bytes we can read now		 * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil		 *                                      other side's read attempt		 * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now		 *		 * ..._read_request is never more than ..._write_guarantee;		 * it depends on the application which one you should use.		 */		/* We have non-blocking behaviour throughout this test program, but		 * can be sure that there is *some* progress in each iteration; so		 * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE		 * -- we just try everything in each iteration		 */			{			/* CLIENT */					MS_STATIC char cbuf[1024*8];			int i, r;			clock_t c_clock = clock();			if (debug)				if (SSL_in_init(c_ssl))					printf("client waiting in SSL_connect - %s\n",						SSL_state_string_long(c_ssl));			if (cw_num > 0)				{				/* Write to server. */								if (cw_num > (long)sizeof cbuf)					i = sizeof cbuf;				else					i = (int)cw_num;				r = BIO_write(c_ssl_bio, cbuf, i);				if (r < 0)					{					if (!BIO_should_retry(c_ssl_bio))						{						fprintf(stderr,"ERROR in CLIENT\n");						goto err;						}					/* BIO_should_retry(...) can just be ignored here.					 * The library expects us to call BIO_write with					 * the same arguments again, and that's what we will					 * do in the next iteration. */					}				else if (r == 0)					{					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");					goto err;					}				else					{					if (debug)						printf("client wrote %d\n", r);					cw_num -= r;									}				}			if (cr_num > 0)				{				/* Read from server. */				r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));				if (r < 0)					{					if (!BIO_should_retry(c_ssl_bio))						{						fprintf(stderr,"ERROR in CLIENT\n");						goto err;						}					/* Again, "BIO_should_retry" can be ignored. */					}				else if (r == 0)					{					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");					goto err;					}				else					{					if (debug)						printf("client read %d\n", r);					cr_num -= r;					}				}			/* c_time and s_time increments will typically be very small			 * (depending on machine speed and clock tick intervals),			 * but sampling over a large number of connections should			 * result in fairly accurate figures.  We cannot guarantee			 * a lot, however -- if each connection lasts for exactly			 * one clock tick, it will be counted only for the client			 * or only for the server or even not at all.			 */			*c_time += (clock() - c_clock);			}			{			/* SERVER */					MS_STATIC char sbuf[1024*8];			int i, r;			clock_t s_clock = clock();			if (debug)				if (SSL_in_init(s_ssl))					printf("server waiting in SSL_accept - %s\n",						SSL_state_string_long(s_ssl));			if (sw_num > 0)				{				/* Write to client. */								if (sw_num > (long)sizeof sbuf)					i = sizeof sbuf;				else					i = (int)sw_num;				r = BIO_write(s_ssl_bio, sbuf, i);				if (r < 0)					{					if (!BIO_should_retry(s_ssl_bio))						{						fprintf(stderr,"ERROR in SERVER\n");						goto err;						}					/* Ignore "BIO_should_retry". */					}				else if (r == 0)					{					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");					goto err;					}				else					{					if (debug)						printf("server wrote %d\n", r);					sw_num -= r;									}				}			if (sr_num > 0)				{				/* Read from client. */				r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));				if (r < 0)					{					if (!BIO_should_retry(s_ssl_bio))						{						fprintf(stderr,"ERROR in SERVER\n");						goto err;						}					/* blah, blah */					}				else if (r == 0)					{					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");					goto err;					}				else					{					if (debug)						printf("server read %d\n", r);					sr_num -= r;					}				}			*s_time += (clock() - s_clock);			}						{			/* "I/O" BETWEEN CLIENT AND SERVER. */			size_t r1, r2;			BIO *io1 = server_io, *io2 = client_io;			/* we use the non-copying interface for io1			 * and the standard BIO_write/BIO_read interface for io2			 */						static int prev_progress = 1;			int progress = 0;						/* io1 to io2 */			do				{				size_t num;				size_t r;				r1 = BIO_ctrl_pending(io1);				r2 = BIO_ctrl_get_write_guarantee(io2);				num = r1;				if (r2 < num)					num = r2;				if (num)					{					char *dataptr;					if (INT_MAX < num) /* yeah, right */						num = INT_MAX;										r = BIO_nread(io1, &dataptr, (int)num);					assert(r > 0);					assert(r <= (int)num);					/* possibly r < num (non-contiguous data) */					num = r;					r = BIO_write(io2, dataptr, (int)num);					if (r != (int)num) /* can't happen */						{						fprintf(stderr, "ERROR: BIO_write could not write "							"BIO_ctrl_get_write_guarantee() bytes");						goto err;						}					progress = 1;					if (debug)						printf((io1 == client_io) ?							"C->S relaying: %d bytes\n" :							"S->C relaying: %d bytes\n",							(int)num);					}				}			while (r1 && r2);			/* io2 to io1 */			{				size_t num;				int r;				r1 = BIO_ctrl_pending(io2);				r2 = BIO_ctrl_get_read_request(io1);				/* here we could use ..._get_write_guarantee instead of				 * ..._get_read_request, but by using the latter				 * we test restartability of the SSL implementation				 * more thoroughly */				num = r1;				if (r2 < num)					num = r2;				if (num)					{					char *dataptr;										if (INT_MAX < num)						num = INT_MAX;					if (num > 1)						--num; /* test restartability even more thoroughly */										r = BIO_nwrite0(io1, &dataptr);					assert(r > 0);					if (r < num)						num = r;					r = BIO_read(io2, dataptr, (int)num);					if (r != (int)num) /* can't happen */						{						fprintf(stderr, "ERROR: BIO_read could not read "							"BIO_ctrl_pending() bytes");						goto err;						}					progress = 1;					r = BIO_nwrite(io1, &dataptr, (int)num);					if (r != (int)num) /* can't happen */						{						fprintf(stderr, "ERROR: BIO_nwrite() did not accept "							"BIO_nwrite0() bytes");						goto err;						}										if (debug)						printf((io2 == client_io) ?							"C->S relaying: %d bytes\n" :							"S->C relaying: %d bytes\n",							(int)num);					}			} /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */			if (!progress && !prev_progress)				if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0)					{					fprintf(stderr, "ERROR: got stuck\n");					if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0)						{						fprintf(stderr, "This can happen for SSL2 because "							"CLIENT-FINISHED and SERVER-VERIFY are written \n"							"concurrently ...");						if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0							&& strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0)							{							fprintf(stderr, " ok.\n");							goto end;							}						}					fprintf(stderr, " ERROR.\n");					goto err;					}			prev_progress = progress;			}		}	while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);	if (verbose)		print_details(c_ssl, "DONE via BIO pair: ");end:	ret = 0; err:	ERR_print_errors(bio_err);		if (server)		BIO_free(server);	if (server_io)		BIO_free(server_io);	if (client)		BIO_free(client);	if (client_io)		BIO_free(client_io);	if (s_ssl_bio)		BIO_free(s_ssl_bio);	if (c_ssl_bio)		BIO_free(c_ssl_bio);	return ret;	}