+/*
+ * Note, we handle the initial connection request here.
+ * We only get the jobname and the SD version, then we
+ * return, authentication will be done when the Director
+ * sends the storage command -- as is usually the case.
+ * This should be called only once by the SD.
+ */
+static void *handle_storage_request(BSOCK *sd)
+{
+ char job_name[500];
+ char tbuf[150];
+ int sd_version;
+ JCR *jcr;
+
+ if (sscanf(sd->msg, "Hello FD: Bacula Storage calling Start Job %127s %d\n",
+ job_name, &sd_version) != 2) {
+ Jmsg(NULL, M_FATAL, 0, _("SD connect failed: Bad Hello command\n"));
+ return NULL;
+ }
+ Dmsg1(110, "Got a SD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf),
+ (utime_t)time(NULL)));
+ Dmsg1(50, "%s", sd->msg);
+
+ if (!(jcr=get_jcr_by_full_name(job_name))) {
+ Jmsg1(NULL, M_FATAL, 0, _("SD connect failed: Job name not found: %s\n"), job_name);
+ Dmsg1(3, "**** Job \"%s\" not found.\n", job_name);
+ sd->destroy();
+ return NULL;
+ }
+
+ Dmsg1(150, "Found Job %s\n", job_name);
+
+ jcr->store_bsock = sd;
+ jcr->store_bsock->set_jcr(jcr);
+
+ if (!jcr->max_bandwidth) {
+ if (jcr->director->max_bandwidth_per_job) {
+ jcr->max_bandwidth = jcr->director->max_bandwidth_per_job;
+
+ } else if (me->max_bandwidth_per_job) {
+ jcr->max_bandwidth = me->max_bandwidth_per_job;
+ }
+ }
+ sd->set_bwlimit(jcr->max_bandwidth);
+ pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
+ free_jcr(jcr);
+ return NULL;
+}
+
+/*
+ * Accept requests from a Director or a Storage daemon
+ */
+void *handle_connection_request(void *caller)
+{
+ BSOCK *bs = (BSOCK *)caller;
+
+ if (bs->recv() > 0) {
+ if (strncmp(bs->msg, "Ping", 4) == 0) {
+ bs->fsend("2000 Ping OK\n");
+ bs->destroy();
+ return NULL;
+ }
+ if (bs->msglen < 25 || bs->msglen > 500) {
+ goto bail_out;
+ }
+ Dmsg1(100, "Got: %s", bs->msg);
+ if (strncmp(bs->msg, "Hello Director", 14) == 0) {
+ return handle_director_request(bs);
+ }
+ if (strncmp(bs->msg, "Hello FD: Bacula Storage", 20) ==0) {
+ return handle_storage_request(bs);
+ }
+ }
+bail_out:
+ Dmsg2(100, "Bad command from %s. Len=%d.\n", bs->who(), bs->msglen);
+ char addr[64];
+ char *who = bs->get_peer(addr, sizeof(addr)) ? bs->who() : addr;
+ Jmsg2(NULL, M_FATAL, 0, _("Bad command from %s. Len=%d.\n"), who, bs->msglen);
+ bs->destroy();
+ return NULL;
+}
+