BIO pairs SourceSink BIOs

78 BIO_do_acceptbio; wait for a new connection new_bio = BIO_popbio; new_bio now behaves like a BIO_s_socket BIO }

4.3.1.4 BIO pairs

The final type of sourcesink BIO that well discuss is a BIO pair. A BIO pair is similar to an anonymous pipe, [1] but does have one important difference. In a BIO pair, two sourcesink BIOs are bound together as peers so that anything written to one can be read from the other. Similarly, an anonymous pipe creates two endpoints, but only one can be written to, and the other is read from. Both endpoints of a BIO pair can be read to and written from. [1] An anonymous pipe is a common operating system construct in which two file descriptors are created, but no file is created or socket opened. The two descriptors are connected to each other where one can be written to and the other read from. The data written to one half of the pipe can be read from the other half of the pipe. A BIO pair can be formed by joining two already existing BIO objects, or two new BIO objects can be created in a joined state. The function BIO_make_bio_pair will join two existing BIO objects created using the BIO_METHOD object returned from the BIO_s_bio function. It accepts two parameters, each one a BIO that will be an endpoint in the resultant pair. When a BIO is created using BIO_s_bio to obtain a BIO_METHOD suitable for use with BIO_new , it must be assigned a buffer with a call to BIO_set_write_buf_size , which accepts two parameters. The first is the BIO to assign the buffer to, and the second is the size in bytes of the buffer to be assigned. New BIO objects can be created already joined with the convenience function BIO_new_bio_pair , which accepts four parameters. The first and third parameters are pointers to BIO objects that will receive a pointer to each newly created BIO object. The second and fourth parameters are the sizes of the buffers to be assigned to each half of the BIO pair. If an error occurs, such as an out of memory condition, the function will return zero; otherwise, it will return nonzero. The function BIO_destroy_bio_pair will sever the pairing of the two endpoints in a BIO pair. This function is useful when you want to break up a pair and reassign one or both of the endpoints to other potential endpoints. The function accepts one parameter, which is one of the endpoints in a pair. It should only be called on one half of a pair, not both. Calling BIO_free will also cleanly sever a pair, but will only free the one endpoint of the pair that is passed to it. One of the useful features of BIO pairs is their ability to use the SSL engine which requires the use of BIO objects while maintaining control over the low-level IO primitives. For example, you could provide an endpoint of a BIO pair to the SSL engine for reading and writing, and then use the other end of the endpoint to read and write the data however you wish. In other words, if the SSL engine writes to the BIO, you can read that data from the other endpoint and do what you wish with it. Likewise, when the SSL engine needs to read data, you write to the other endpoint, and the SSL engine will read it. Included in the OpenSSL distribution is a test application the source file is sslssltest.c that is a good example of how to use BIO pairs. It implements a client and a server in the same application. The client and the server talk to each other within the same application without requiring sockets or some other low-level communication mechanism. Example 4-7 demonstrates how BIO pairs can be created, detached, and reattached. Example 4-7. Creating BIO pairs a = BIO_newBIO_s_bio; BIO_set_write_buf_sizea, 4096; 79 b = BIO_newBIO_s_bio; BIO_set_write_buf_sizeb, 4096; BIO_make_bio_paira, b; BIO_new_bio_paira, 8192, b, 8192; c = BIO_newBIO_s_bio; BIO_set_write_buf_sizec, 1024; BIO_destroy_bio_paira; disconnect a from b BIO_make_bio_paira, c;

4.3.2 Filter BIOs