1%%
2%%
3
4\chapter{TCP/IP Network Protocol}
5\label{blb:TheChapterStart5}
6\index{TCP/IP Network Protocol}
7\index{Protocol!TCP/IP Network}
8
9\section{General}
10\index{General}
11
12This document describes the TCP/IP protocol used by Bacula to communicate
13between the various daemons and services. The definitive definition of the
14protocol can be found in src/lib/bsock.h, src/lib/bnet.c and
15src/lib/bnet\_server.c.
16
17Bacula's network protocol is basically a \bog{}packet oriented\cog{} protocol built on
18a standard TCP/IP streams. At the lowest level all packet transfers are done
19with read() and write() requests on system sockets. Pipes are not used as they
20are considered unreliable for large serial data transfers between various
21hosts.
22
23Using the routines described below (bnet\_open, bnet\_write, bnet\_recv, and
24bnet\_close) guarantees that the number of bytes you write into the socket
25will be received as a single record on the other end regardless of how many
26low level write() and read() calls are needed. All data transferred are
27considered to be binary data.
28
29\section{bnet and Threads}
30\index{Threads!bnet and}
31\index{Bnet and Threads}
32
33These bnet routines work fine in a threaded environment. However, they assume
34that there is only one reader or writer on the socket at any time. It is
35highly recommended that only a single thread access any BSOCK packet. The
36exception to this rule is when the socket is first opened and it is waiting
37for a job to start. The wait in the Storage daemon is done in one thread and
38then passed to another thread for subsequent handling.
39
40If you envision having two threads using the same BSOCK, think twice, then you
41must implement some locking mechanism. However, it probably would not be
42appropriate to put locks inside the bnet subroutines for efficiency reasons.
43
44\section{bnet\_open}
45\index{Bnet\_open}
46
47To establish a connection to a server, use the subroutine:
48
49BSOCK *bnet\_open(void *jcr, char *host, char *service, int port,  int *fatal)
50bnet\_open(), if successful, returns the Bacula sock descriptor pointer to be
51used in subsequent bnet\_send() and bnet\_read() requests. If not successful,
52bnet\_open() returns a NULL. If fatal is set on return, it means that a fatal
53error occurred and that you should not repeatedly call bnet\_open(). Any error
54message will generally be sent to the JCR.
55
56\section{bnet\_send}
57\index{Bnet\_send}
58
59To send a packet, one uses the subroutine:
60
61int bnet\_send(BSOCK *sock) This routine is equivalent to a write() except
62that it handles the low level details. The data to be sent is expected to be
63in sock-\gt{}msg and be sock-\gt{}msglen bytes. To send a packet, bnet\_send()
64first writes four bytes in network byte order than indicate the size of the
65following data packet. It returns:
66
67\begin{bVerbatim}
68 Returns 0 on failure
69 Returns 1 on success
70\end{bVerbatim}
71
72In the case of a failure, an error message will be sent to the JCR contained
73within the bsock packet.
74
75\section{bnet\_fsend}
76\index{Bnet\_fsend}
77
78This form uses:
79
80int bnet\_fsend(BSOCK *sock, char *format, ...) and it allows you to send a
81formatted messages somewhat like fprintf(). The return status is the same as
82bnet\_send.
83
84\section{Additional Error information}
85\index{Information!Additional Error}
86\index{Additional Error information}
87
88For additional error information, you can call {\bf is\_bnet\_error(BSOCK
89*bsock)} which will return 0 if there is no error or non-zero if there is an
90error on the last transmission. The {\bf is\_bnet\_stop(BSOCK *bsock)}
91function will return 0 if there no errors and you can continue sending. It
92will return non-zero if there are errors or the line is closed (no more
93transmissions should be sent).
94
95\section{bnet\_recv}
96\index{Bnet\_recv}
97
98To read a packet, one uses the subroutine:
99
100int bnet\_recv(BSOCK *sock) This routine is similar to a read() except that it
101handles the low level details. bnet\_read() first reads packet length that
102follows as four bytes in network byte order. The data is read into
103sock-\gt{}msg and is sock-\gt{}msglen bytes. If the sock-\gt{}msg is not large
104enough, bnet\_recv() realloc() the buffer. It will return an error (-2) if
105maxbytes is less than the record size sent. It returns:
106
107\begin{bVerbatim}
108 * Returns number of bytes read
109 * Returns 0 on end of file
110 * Returns -1 on hard end of file (i.e. network connection close)
111 * Returns -2 on error
112\end{bVerbatim}
113
114It should be noted that bnet\_recv() is a blocking read.
115
116\section{bnet\_sig}
117\index{Bnet\_sig}
118
119To send a \bog{}signal\cog{} from one daemon to another, one uses the subroutine:
120
121int bnet\_sig(BSOCK *sock, SIGNAL) where SIGNAL is one of the following:
122
123\begin{benumerate}
124\item BNET\_EOF - deprecated use BNET\_EOD
125\item BNET\_EOD - End of data stream, new data may follow
126\item BNET\_EOD\_POLL - End of data and poll all in one
127\item BNET\_STATUS - Request full status
128\item BNET\_TERMINATE - Conversation terminated, doing close()
129\item BNET\_POLL - Poll request, I'm hanging on a read
130\item BNET\_HEARTBEAT - Heartbeat Response requested
131\item BNET\_HB\_RESPONSE - Only response permitted to HB
132\item BNET\_PROMPT - Prompt for UA
133   \end{benumerate}
134
135\section{bnet\_strerror}
136\index{Bnet\_strerror}
137
138Returns a formated string corresponding to the last error that occurred.
139
140\section{bnet\_close}
141\index{Bnet\_close}
142
143The connection with the server remains open until closed by the subroutine:
144
145void bnet\_close(BSOCK *sock)
146
147\section{Becoming a Server}
148\index{Server!Becoming a}
149\index{Becoming a Server}
150
151The bnet\_open() and bnet\_close() routines described above are used on the
152client side to establish a connection and terminate a connection with the
153server. To become a server (i.e. wait for a connection from a client), use the
154routine {\bf bnet\_thread\_server}. The calling sequence is a bit complicated,
155please refer to the code in bnet\_server.c and the code at the beginning of
156each daemon as examples of how to call it.
157
158\section{Higher Level Conventions}
159\index{Conventions!Higher Level}
160\index{Higher Level Conventions}
161
162Within Bacula, we have established the convention that any time a single
163record is passed, it is sent with bnet\_send() and read with bnet\_recv().
164Thus the normal exchange between the server (S) and the client (C) are:
165
166\begin{bVerbatim}
167S: wait for connection            C: attempt connection
168S: accept connection              C: bnet_send() send request
169S: bnet_recv() wait for request
170S: act on request
171S: bnet_send() send ack            C: bnet_recv() wait for ack
172\end{bVerbatim}
173
174Thus a single command is sent, acted upon by the server, and then
175acknowledged.
176
177In certain cases, such as the transfer of the data for a file, all the
178information or data cannot be sent in a single packet. In this case, the
179convention is that the client will send a command to the server, who knows
180that more than one packet will be returned. In this case, the server will
181enter a loop:
182
183\begin{bVerbatim}
184while ((n=bnet_recv(bsock)) > 0) {
185   act on request
186}
187if (n < 0)
188   error
189\end{bVerbatim}
190
191The client will perform the following:
192
193\begin{bVerbatim}
194bnet_send(bsock);
195bnet_send(bsock);
196...
197bnet_sig(bsock, BNET_EOD);
198\end{bVerbatim}
199
200Thus the client will send multiple packets and signal to the server when all
201the packets have been sent by sending a zero length record.
202