void signal_quit(int sig) { if (!keep_running) raise(sig); keep_running = 0; ts_LOGf("Killed %s with signal %d\n", program_id, sig); if (ts.input.type == NET_IO) shutdown_fd(&ts.input.fd); if (ts.output.type == NET_IO) shutdown_fd(&ts.output.fd); signal(sig, SIG_DFL); }
static void accept_connection_cb (FsMsnConnection *self, FsMsnPollFD *pollfd) { struct sockaddr_in in; int fd = -1; socklen_t n = sizeof (in); if (gst_poll_fd_has_error (self->poll, &pollfd->pollfd) || gst_poll_fd_has_closed (self->poll, &pollfd->pollfd)) { GST_WARNING ("Error in accept socket : %d", pollfd->pollfd.fd); goto error; } if ((fd = accept(pollfd->pollfd.fd, (struct sockaddr*) &in, &n)) == -1) { GST_ERROR ("Error while running accept() %d", errno); return; } FS_MSN_CONNECTION_LOCK (self); add_pollfd_locked (self, fd, connection_cb, TRUE, FALSE, TRUE); FS_MSN_CONNECTION_UNLOCK (self); return; /* Error */ error: GST_WARNING ("Got error from fd %d, closing", fd); // find, shutdown and remove channel from fdlist shutdown_fd (self, pollfd, TRUE); return; }
static void successful_connection_cb (FsMsnConnection *self, FsMsnPollFD *pollfd) { gint error; socklen_t option_len; GST_DEBUG ("handler called on fd %d", pollfd->pollfd.fd); errno = 0; if (gst_poll_fd_has_error (self->poll, &pollfd->pollfd) || gst_poll_fd_has_closed (self->poll, &pollfd->pollfd)) { GST_WARNING ("connecton closed or error"); goto error; } option_len = sizeof(error); /* Get the error option */ if (getsockopt(pollfd->pollfd.fd, SOL_SOCKET, SO_ERROR, (void*) &error, &option_len) < 0) { g_warning ("getsockopt() failed"); goto error; } /* Check if there is an error */ if (error) { GST_WARNING ("getsockopt gave an error : %d", error); goto error; } pollfd->callback = connection_cb; GST_DEBUG ("connection succeeded on socket %p", pollfd); return; /* Error */ error: GST_WARNING ("Got error from fd %d, closing", pollfd->pollfd.fd); // find, shutdown and remove channel from fdlist shutdown_fd (self, pollfd, TRUE); return; }
static void connection_cb (FsMsnConnection *self, FsMsnPollFD *pollfd) { gboolean success = FALSE; GST_DEBUG ("handler called on fd:%d server: %d status:%d r:%d w:%d", pollfd->pollfd.fd, pollfd->server, pollfd->status, gst_poll_fd_can_read (self->poll, &pollfd->pollfd), gst_poll_fd_can_write (self->poll, &pollfd->pollfd)); if (gst_poll_fd_has_error (self->poll, &pollfd->pollfd) || gst_poll_fd_has_closed (self->poll, &pollfd->pollfd)) { GST_WARNING ("connecton closed or error (error: %d closed: %d)", gst_poll_fd_has_error (self->poll, &pollfd->pollfd), gst_poll_fd_has_closed (self->poll, &pollfd->pollfd)); goto error; } if (gst_poll_fd_can_read (self->poll, &pollfd->pollfd)) { switch (pollfd->status) { case FS_MSN_STATUS_AUTH: if (pollfd->server) { gchar str[35] = {0}; gchar check[35] = {0}; if (recv (pollfd->pollfd.fd, str, 34, 0) == 34) { GST_DEBUG ("Got %s, checking if it's auth", str); FS_MSN_CONNECTION_LOCK(self); snprintf(check, 35, "recipientid=%s&sessionid=%d\r\n\r\n", self->local_recipient_id, self->session_id); FS_MSN_CONNECTION_UNLOCK(self); if (strncmp (str, check, 35) == 0) { GST_DEBUG ("Authentication successful"); pollfd->status = FS_MSN_STATUS_CONNECTED; pollfd->want_write = TRUE; gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, TRUE); } else { GST_WARNING ("Authentication failed check=%s", check); goto error; } } else { gchar error_str[256]; strerror_r (errno, error_str, 256); GST_WARNING ("auth: %s", error_str); goto error; } } else { GST_ERROR ("shouldn't receive data when client on AUTH state"); goto error; } break; case FS_MSN_STATUS_CONNECTED: if (!pollfd->server) { gchar str[14] = {0}; ssize_t size; size = recv (pollfd->pollfd.fd, str, 13, MSG_PEEK); if (size > 0) { GST_DEBUG ("Got %s, checking if it's connected", str); if (size == 13 && strcmp (str, "connected\r\n\r\n") == 0) { GST_DEBUG ("connection successful"); recv (pollfd->pollfd.fd, str, 13, 0); pollfd->status = FS_MSN_STATUS_CONNECTED2; pollfd->want_write = TRUE; gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, TRUE); } else if (!self->producer) { GST_DEBUG ("connection successful"); pollfd->status = FS_MSN_STATUS_SEND_RECEIVE; success = TRUE; } else { GST_WARNING ("connected failed"); goto error; } } else { gchar error_str[256]; strerror_r (errno, error_str, 256); GST_WARNING ("recv: %s", error_str); goto error; } } else { GST_ERROR ("shouldn't receive data when server on CONNECTED state"); goto error; } break; case FS_MSN_STATUS_CONNECTED2: if (pollfd->server) { gchar str[14] = {0}; ssize_t size; size = recv (pollfd->pollfd.fd, str, 13, MSG_PEEK); if (size > 0) { GST_DEBUG ("Got %s, checking if it's connected", str); if (size == 13 && strcmp (str, "connected\r\n\r\n") == 0) { GST_DEBUG ("connection successful"); recv (pollfd->pollfd.fd, str, 13, 0); pollfd->status = FS_MSN_STATUS_SEND_RECEIVE; success = TRUE; } else if (!self->producer) { GST_DEBUG ("connection successful"); pollfd->status = FS_MSN_STATUS_SEND_RECEIVE; success = TRUE; } else { GST_WARNING ("connected failed"); goto error; } } else { gchar error_str[256]; strerror_r (errno, error_str, 256); GST_WARNING ("recv: %s", error_str); goto error; } } else { GST_ERROR ("shouldn't receive data when client on CONNECTED2 state"); goto error; } break; default: GST_ERROR ("Invalid status %d", pollfd->status); goto error; break; } } else if (gst_poll_fd_can_write (self->poll, &pollfd->pollfd)) { pollfd->want_write = FALSE; gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, FALSE); switch (pollfd->status) { case FS_MSN_STATUS_AUTH: if (!pollfd->server) { gchar *str; FS_MSN_CONNECTION_LOCK(self); str = g_strdup_printf("recipientid=%s&sessionid=%d\r\n\r\n", self->remote_recipient_id, self->session_id); FS_MSN_CONNECTION_UNLOCK(self); if (send(pollfd->pollfd.fd, str, strlen (str), 0) != -1) { GST_DEBUG ("Sent %s", str); pollfd->status = FS_MSN_STATUS_CONNECTED; g_free (str); } else { gchar error_str[256]; strerror_r (errno, error_str, 256); GST_WARNING ("auth send: %s", error_str); g_free (str); goto error; } } break; case FS_MSN_STATUS_CONNECTED: if (pollfd->server) { if (send(pollfd->pollfd.fd, "connected\r\n\r\n", 13, 0) != -1) { GST_DEBUG ("sent connected"); if (self->producer) { pollfd->status = FS_MSN_STATUS_SEND_RECEIVE; success = TRUE; } else { pollfd->status = FS_MSN_STATUS_CONNECTED2; } } else { gchar error_str[256]; strerror_r (errno, error_str, 256); GST_WARNING ("sending connected: %s", error_str); goto error; } } else { GST_DEBUG ("shouldn't receive data when server on CONNECTED state"); goto error; } break; case FS_MSN_STATUS_CONNECTED2: if (!pollfd->server) { if (send(pollfd->pollfd.fd, "connected\r\n\r\n", 13, 0) != -1) { GST_DEBUG ("sent connected"); pollfd->status = FS_MSN_STATUS_SEND_RECEIVE; success = TRUE; } else { gchar error_str[256]; strerror_r (errno, error_str, 256); GST_WARNING ("sending connected: %s", error_str); goto error; } } else { GST_ERROR ("shouldn't receive data when client on CONNECTED2 state"); goto error; } break; default: GST_ERROR ("Invalid status %d", pollfd->status); goto error; break; } } if (success) { // success! we need to shutdown/close all other channels shutdown_fd (self, pollfd, FALSE); g_signal_emit (self, signals[SIGNAL_CONNECTED], 0, pollfd->pollfd.fd); pollfd->want_read = FALSE; pollfd->want_write = FALSE; gst_poll_fd_ctl_read (self->poll, &pollfd->pollfd, FALSE); gst_poll_fd_ctl_write (self->poll, &pollfd->pollfd, FALSE); } return; error: /* Error */ GST_WARNING ("Got error from fd %d, closing", pollfd->pollfd.fd); shutdown_fd (self, pollfd, TRUE); FS_MSN_CONNECTION_LOCK (self); success = (self->pollfds->len > 1); FS_MSN_CONNECTION_UNLOCK (self); if (!success) g_signal_emit (self, signals[SIGNAL_CONNECTION_FAILED], 0); return; }