To be able to use GCB, applications must call GCB functions. We call this process of making an application GCB-enabled GCBnize. A GCBnized program must calls the following functions instead of regular counterparts:
- Sockets calls: GCB_socket, GCB_bind, GCB_listen, GCB_connect, GCB_accept, GCB_recv, GCB_recvfrom, GCB_send, GCB_sendto, GCB_getsockname, GCB_getsockaddr, GCB_getsockopt
- File system related calls: GCB_select, GCB_read, GCB_write, GCB_close, GCB_dup, GCB_dup2, GCB_fcntl
- Process control calls: GCB_execve
You can make an application GCBnized either by:
- explicilty (re)writing the application to call GCB functions. If you have source codes of the application, the this may be the best option to take. Please read GCB-friendly Guide.
- statically interposing the application. Some linkers such as GNU linker provide options to replace (or wrap) system calls with arbitrary function. If you are using one of these linkers, then you can GCBnize your application using this mechanism. The file for wrapping necessary functions is included in the current release. To statically interpose your application, add the following options (as a single line) to your link command:
-Wl,--wrap,socket -Wl,--wrap,bind -Wl,--wrap,listen -Wl,--wrap,connect -Wl,--wrap,accept -Wl,--wrap,select -Wl,--wrap,recv -Wl,--wrap,read -Wl,--wrap,recvfrom -Wl,--wrap,send -Wl,--wrap,sendto -Wl,--wrap,write -Wl,--wrap,close -Wl,--wrap,dup -Wl,--wrap,dup2 -Wl,--wrap,getsockname -Wl,--wrap,getsockaddr -Wl,--wrap,getsockopt -Wl,--wrap,execv -Wl,--wrap,execl -Wl,--wrap,execve
Therefore, your link line should be something similar to:
ld your_link_options -Wl,--wrap,socket ... -Wl,--wrap,execve libGCB.a
Note: even if you choose to use the 2nd or 3rd option, I would recommend you to still read GCB-friendly Guide. Even though I tried my best to make GCB calls have the same semantics as the corresponding Berkeley socket calls, some GCB calls have slightly different semantics from corresponding socket calls.
GCB-friendly Guide
Because of address leasing (See How GCB Works) and extra communications with the GCB inagent, GCB has different semantics for some calls and therefore has serveral programming constraints.
- It is always safe to use GCB functions instead of regular socket calls even for non-GCB socket and regular file descriptors. For example, you can safely use GCB_close for a regular file. GCB knows what fds it is in charge of. Especially it is very unsafe for applications to blindly call close. This happens in some applications because calling close for invalid fd does not do any harm. For example, a child process of some applications blindly closes every fd except a few that it needs to use. To communicate with the inagent, GCB may create sockets without application's notice. If these sockets that GCB uses for its own purpose are closed without GCB's awareness, GCB will have a bad information
- Applications should not choose IP address to bind a socket. This means that the application must call GCB_bind with IP = INADDR_ANY and ask GCB, by calling GCB_getsockname, whenever it needs to know the address that the socket is bound to. Applications can still designate port number to bind.
- GCB_bind and GCB_listen are blocking calls, meaning that these calls may take from few micro seconds to few ten seconds in the worst case and the application will be blocked until the operation completes. This does not affect programming much and, because these are one-time operations for socket lifetime, I believe that they have little performance effect.