static handler_t mod_proxy_connection_close_callback(server *srv, connection *con, void *p_d) { plugin_data *p = p_d; proxy_connection_close(srv, con->plugin_ctx[p->id]); return HANDLER_GO_ON; }
static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) { handler_ctx *hctx = ctx; connection *con = hctx->remote_conn; plugin_data *p = hctx->plugin_data; if ((revents & FDEVENT_IN) && hctx->state == PROXY_STATE_READ) { if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: fdevent-in", hctx->state); } switch (proxy_demux_response(srv, hctx)) { case 0: break; case 1: /* we are done */ proxy_connection_close(srv, hctx); joblist_append(srv, con); return HANDLER_FINISHED; case -1: if (con->file_started == 0) { /* nothing has been send out yet, send a 500 */ connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); con->http_status = 500; con->mode = DIRECT; } else { /* response might have been already started, kill the connection */ connection_set_state(srv, con, CON_STATE_ERROR); } joblist_append(srv, con); return HANDLER_FINISHED; } } if (revents & FDEVENT_OUT) { if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: fdevent-out", hctx->state); } if (hctx->state == PROXY_STATE_CONNECT) { int socket_error; socklen_t socket_error_len = sizeof(socket_error); /* we don't need it anymore */ fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); hctx->fde_ndx = -1; /* try to finish the connect() */ if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) { log_error_write(srv, __FILE__, __LINE__, "ss", "getsockopt failed:", strerror(errno)); joblist_append(srv, con); return HANDLER_FINISHED; } if (socket_error != 0) { log_error_write(srv, __FILE__, __LINE__, "ss", "establishing connection failed:", strerror(socket_error), "port:", hctx->host->port); joblist_append(srv, con); return HANDLER_FINISHED; } if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "s", "proxy - connect - delayed success"); } proxy_set_state(srv, hctx, PROXY_STATE_PREPARE_WRITE); } if (hctx->state == PROXY_STATE_PREPARE_WRITE || hctx->state == PROXY_STATE_WRITE) { /* we are allowed to send something out * * 1. after a just finished connect() call * 2. in a unfinished write() call (long POST request) */ return mod_proxy_handle_subrequest(srv, con, p); } else { log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: out", hctx->state); } } /* perhaps this issue is already handled */ if (revents & FDEVENT_HUP) { if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: fdevent-hup", hctx->state); } if (hctx->state == PROXY_STATE_CONNECT) { /* connect() -> EINPROGRESS -> HUP */ /** * what is proxy is doing if it can't reach the next hop ? * */ if (hctx->host) { hctx->host->is_disabled = 1; hctx->host->disable_ts = srv->cur_ts; log_error_write(srv, __FILE__, __LINE__, "sbdd", "proxy-server disabled:", hctx->host->host, hctx->host->port, hctx->fd); /* disable this server */ hctx->host->is_disabled = 1; hctx->host->disable_ts = srv->cur_ts; proxy_connection_close(srv, hctx); /* reset the enviroment and restart the sub-request */ buffer_reset(con->physical.path); con->mode = DIRECT; joblist_append(srv, con); } else { proxy_connection_close(srv, hctx); joblist_append(srv, con); con->mode = DIRECT; con->http_status = 503; } return HANDLER_FINISHED; } if (!con->file_finished) { http_chunk_append_mem(srv, con, NULL, 0); } con->file_finished = 1; proxy_connection_close(srv, hctx); joblist_append(srv, con); } else if (revents & FDEVENT_ERR) { /* kill all connections to the proxy process */ log_error_write(srv, __FILE__, __LINE__, "sd", "proxy-FDEVENT_ERR, but no HUP", revents); con->file_finished = 1; joblist_append(srv, con); proxy_connection_close(srv, hctx); } return HANDLER_FINISHED; }
static handler_t proxy_handle_fdevent(void *s, void *ctx, int revents) { server *srv = (server *)s; handler_ctx *hctx = ctx; connection *con = hctx->remote_conn; plugin_data *p = hctx->plugin_data; if ((revents & FDEVENT_IN) && hctx->state == PROXY_STATE_READ) { if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: fdevent-in", hctx->state); } switch (proxy_demux_response(srv, hctx)) { case 0: break; case 1: hctx->host->usage--; /* we are done */ proxy_connection_close(srv, hctx); joblist_append(srv, con); return HANDLER_FINISHED; case -1: if (con->file_started == 0) { /* nothing has been send out yet, send a 500 */ connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); con->http_status = 500; con->mode = DIRECT; } else { /* response might have been already started, kill the connection */ connection_set_state(srv, con, CON_STATE_ERROR); } joblist_append(srv, con); return HANDLER_FINISHED; } } if (revents & FDEVENT_OUT) { if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: fdevent-out", hctx->state); } if (hctx->state == PROXY_STATE_CONNECT || hctx->state == PROXY_STATE_WRITE) { /* we are allowed to send something out * * 1. in a unfinished connect() call * 2. in a unfinished write() call (long POST request) */ return mod_proxy_handle_subrequest(srv, con, p); } else { log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: out", hctx->state); } } /* perhaps this issue is already handled */ if (revents & FDEVENT_HUP) { if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: fdevent-hup", hctx->state); } if (hctx->state == PROXY_STATE_CONNECT) { /* connect() -> EINPROGRESS -> HUP */ /** * what is proxy is doing if it can't reach the next hop ? * */ proxy_connection_close(srv, hctx); joblist_append(srv, con); con->http_status = 503; con->mode = DIRECT; return HANDLER_FINISHED; } con->file_finished = 1; proxy_connection_close(srv, hctx); joblist_append(srv, con); } else if (revents & FDEVENT_ERR) { /* kill all connections to the proxy process */ log_error_write(srv, __FILE__, __LINE__, "sd", "proxy-FDEVENT_ERR, but no HUP", revents); joblist_append(srv, con); proxy_connection_close(srv, hctx); } return HANDLER_FINISHED; }
void on_data_available(gpointer tab, gint fd, GdkInputCondition cond) { GtkWidget *notebook, *top; gchar *buff = NULL; gsize len = 0; SESSION_STATE *session; session = g_object_get_data(G_OBJECT(tab), "session"); telnet_process(session->telnet, &buff, &len); //if nothing to process - don't process if( len > 0 ) process_text(session, buff, len); // if top != current window change title top = gtk_widget_get_toplevel(GTK_WIDGET(tab)); //if (top != interface_get_active_window()) { if (!gtk_window_is_active(GTK_WINDOW(top))) { gchar *icon; gtk_window_set_title(GTK_WINDOW(top), "### MudMagic ###"); icon = g_build_filename( mudmagic_data_directory(), "interface", "mudmagic2.xpm", NULL); gtk_window_set_icon_from_file(GTK_WINDOW(top), icon, NULL); g_free(icon); } if (session->telnet->fd < 0 ) // connection close occurs { GtkWidget *wid, *message; gchar *label; gint response; gtk_input_remove(session->input_event_id); session->input_event_id = -1; wid = g_object_get_data(G_OBJECT(session->tab), "input1_entry"); g_return_if_fail(wid != NULL); if ( ! gtk_entry_get_visibility (GTK_ENTRY(wid)) ) { interface_input_shadow(session, FALSE); gtk_entry_set_text(GTK_ENTRY(wid), ""); } while (1) { wid = interface_create_object_by_name ("dialog_connection_close"); if (wid == NULL) { g_warning ("can't create 'dialog_connection_close"); } message = interface_get_widget(wid, "connection_close_message"); if (message == NULL) { g_warning ("can't get 'dialog_connection_close"); } label = g_strdup_printf ("Connection to %s:%d has been close.", session->game_host, session->game_port); gtk_label_set_text(GTK_LABEL(message), label); g_free(label); response = gtk_dialog_run(GTK_DIALOG(wid)); gtk_widget_destroy(wid); if (response == 0) { // stay disconnect break; } if (response == 1) { // try to reconnect if (session->pconn) proxy_connection_close (session->pconn); session->pconn = proxy_connection_open( session->game_host, session->game_port, proxy_get_by_name (session->proxy, config->proxies) ); if (session->pconn) session->telnet->fd = session->pconn->sock; else session->telnet->fd = NO_CONNECTION; if (session->telnet->fd == NO_CONNECTION ) { interface_messagebox (GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, network_errmsg (session->telnet->fd)); continue; } session->input_event_id = gtk_input_add_full(session->telnet->fd, GDK_INPUT_READ,(GdkInputFunction)on_data_available, NULL, tab, NULL); break; } if (response == 2) { // close tab interface_remove_tab(tab); return; } } } // if tab != current tab change label color notebook = gtk_widget_get_ancestor(tab, GTK_TYPE_NOTEBOOK); if (notebook) { GtkWidget *label; GtkWidget *current_tab; current_tab = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), gtk_notebook_get_current_page (GTK_NOTEBOOK(notebook)) ); if (tab != current_tab) { label = gtk_notebook_get_tab_label(GTK_NOTEBOOK (notebook), GTK_WIDGET(tab)); if (label) { GtkWidget* icon; icon = g_object_get_data (G_OBJECT (label), "label_icon"); gtk_image_set_from_stock (GTK_IMAGE (icon), GTK_STOCK_NO, GTK_ICON_SIZE_MENU); } } } }