Socket sourcessinks SourceSink BIOs

76 Two types of file BIOs are available: buffered and unbuffered. A buffered file BIO is a wrapper around the standard C runtime FILE object and its related functions. An unbuffered file BIO is a wrapper around a file descriptor and its related functions. With the exception of how the two different types of file BIOs are created, the interface for using them is essentially the same. A buffered file BIO can be created by using BIO_s_file to obtain a BIO_METHOD object suitable for use with BIO_new and BIO_set . Alternatively, BIO_new_file can be used the same way as the standard C runtime function, fopen , is used, or BIO_new_fp can be used to create a BIO around an already existing FILE object. Using BIO_new_fp , you must specify the FILE object to use and a flag indicating whether the FILE object should be closed when the BIO is destroyed. An unbuffered file BIO can be created by using BIO_s_fd to obtain a BIO_METHOD object suitable for use with BIO_new and BIO_set . Alternatively, BIO_new_fd can be used in the same way that BIO_new_fp cis used for buffered BIOs. The difference is that a file descriptor rather than a FILE object must be specified. For either a buffered or an unbuffered file BIO created with BIO_new or BIO_set , additional work must be done to make the BIO usable. Initially, no underlying file object is attached to the BIO, and any read or write operations performed on the BIO always fail. Unbuffered file types of BIOs require that BIO_set_fd be used to attach a file descriptor to the BIO. Buffered file types of BIOs require that BIO_set_file be used to attach a FILE object to the BIO, or one of BIO_read_filename , BIO_write_filename , BIO_append_filename , or BIO_rw_filename be used to create an underlying FILE object with the appropriate mode for the BIO. Example 4-5 shows how to create a file BIO. Example 4-5. Creating a file BIO Create a buffered file BIO with an existing FILE object that will be closed when the BIO is destroyed. file = fopenfilename.ext, r+; bio = BIO_newBIO_s_file; BIO_set_filebio, file, BIO_CLOSE; Create an unbuffered file BIO with an existing file descriptor that will not be closed when the BIO is destroyed. fd = openfilename.ext, O_RDWR; bio = BIO_newBIO_s_fd; BIO_set_fdbio, fd, BIO_NOCLOSE; Create a buffered file BIO with a new FILE object owned by the BIO bio = BIO_new_filefilename.ext, w; Create an unbuffered file BIO with an existing file descriptor that will be closed when the BIO is destroyed. fd = openfilename.ext, O_RDONLY; bio = BIO_new_fdfd, BIO_CLOSE;

4.3.1.3 Socket sourcessinks

There are three types of socket BIOs. The simplest is a socket BIO that must have an already existing socket descriptor attached to it. Such a BIO can be created using BIO_s_socket to obtain a BIO_METHOD object suitable for use with BIO_new and BIO_set . The socket descriptor can then be attached to the BIO using BIO_set_fd . This type of BIO works almost like an 77 unbuffered file BIO. Alternatively, BIO_new_socket can be used in the same way that BIO_new_fd works for unbuffered file BIOs. The second type of BIO socket is a connection socket. This type of BIO creates a new socket that is initially unconnected. The IP address and port to connect to must be set, and the connection established before data can be read from or written to the BIO. BIO_s_connect is used to obtain a BIO_METHOD object suitable for use with BIO_new and BIO_set . To set the address, either BIO_set_conn_hostname can be used to set the hostname or BIO_set_conn_ip can be used to set the IP address in dotted decimal form. Both functions take the connection address as a C-style string. The port to connect to is set using BIO_set_conn_port or BIO_set_conn_int_port . The difference between the two is that BIO_set_conn_port takes the port number as a string, which can be either a port number or a service name such as http or https, and BIO_set_conn_int_port takes the port number as an integer. Once the address and port are set for making a connection, an attempt to establish a connection can be made via BIO_do_connect . Once a connection is successfully established, the BIO can be used just as if it was a plain socket BIO. The third type of BIO socket is an accept socket. This type of BIO creates a new socket that will listen for incoming connections and accept them. When a connection is established, a new BIO object is created that is bound to the accepted socket. The new BIO object is chained to the original BIO and should be disconnected from the chain before use. Data can be read or written with the new BIO object. The original BIO object can then be used to accept more connections. In order to create an accept socket type of socket BIO, use BIO_s_accept to obtain a BIO_METHOD object suitable for use with BIO_new and BIO_set . The port used to listen for connections must be set before the BIO can be placed into listening mode. This can be done using BIO_set_accept_port , which accepts the port as a string. The port can be either a number or the name of a service, just like with BIO_set_conn_port . Once the port is set, BIO_do_accept will place the BIOs socket into listening mode. Successive calls to BIO_do_accept will block until a new connection is established. Example 4-6 demonstrates. Example 4-6. Creating a socket BIO Create a socket BIO attached to an already existing socket descriptor. The socket descriptor will not be closed when the BIO is destroyed. bio = BIO_newBIO_s_socket; BIO_set_fdbio, sd, BIO_NOCLOSE; Create a socket BIO attached to an already existing socket descriptor. The socket descriptor will be closed when the BIO is destroyed. bio = BIO_new_socketsd, BIO_CLOSE; Create a socket BIO to establish a connection to a remote host. bio = BIO_newBIO_s_connect; BIO_set_conn_hostnamebio, www.ora.com; BIO_set_conn_portbio, http; BIO_do_connectbio; Create a socket BIO to listen for an incoming connection. bio = BIO_newBIO_s_accept; BIO_set_accept_portbio, https; BIO_do_acceptbio; place the underlying socket into listening mode for ;; { 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