static void ccnd_stats_http_set_debug(struct ccnd_handle *h, struct face *face, int level) { struct ccn_charbuf *response = ccn_charbuf_create(); h->debug = 1; ccnd_msg(h, "CCND_DEBUG=%d", level); h->debug = level; ccn_charbuf_putf(response, "<title>CCND_DEBUG=%d</title><tt>CCND_DEBUG=%d</tt>" CRLF, level, level); send_http_response(h, face, "text/html", response); ccn_charbuf_destroy(&response); }
/* process command within a request */ static int process_command( int new_sockfd, struct server_ctx* ctx, const char* param, size_t plen ) { int rc = 0; const int STAT_OPTIONS = 0; const int RESTART_OPTIONS = MSO_SKIP_CLIENTS | MSO_RESTART; assert( (new_sockfd > 0) && ctx && param ); if( 0 == strncmp( ctx->cmd, CMD_UDP, sizeof(ctx->cmd) ) || 0 == strncmp( ctx->cmd, CMD_RTP, sizeof(ctx->cmd) ) ) { if( ctx->clfree ) { rc = udp_relay( new_sockfd, param, plen, &(ctx->mcast_inaddr), ctx ); } else { send_http_response( new_sockfd, 401, "Bad request" ); (void)tmfprintf( g_flog, "Client limit [%d] has been reached.\n", ctx->clmax); } } else if( 0 == strncmp( ctx->cmd, CMD_STATUS, sizeof(ctx->cmd) ) ) { rc = report_status( new_sockfd, ctx, STAT_OPTIONS ); } else if( 0 == strncmp( ctx->cmd, CMD_RESTART, sizeof(ctx->cmd) ) ) { (void) report_status( new_sockfd, ctx, RESTART_OPTIONS ); terminate_all_clients( ctx ); wait_all( ctx ); } else { TRACE( (void)tmfprintf( g_flog, "Unrecognized command [%s]" " - ignoring.\n", ctx->cmd) ); send_http_response( new_sockfd, 401, "Unrecognized request" ); } return rc; }
/* Display the console Web page */ void show_web_ui(int csock, char *request) { char *data = NULL; int data_size = 0; if(!request) { glog("NULL request received by Web UI",LOG_ERROR_TYPE); return; } /* Point data at the data blob associated with the requested URL */ if(strstr(request,BODY_BG_PNG_PATH)) { data = BODY_BG_PNG; data_size = BODY_BG_PNG_SIZE; } else if(strstr(request,HEADER_PNG_PATH)) { data = HEADER_PNG; data_size = HEADER_PNG_SIZE; } else if(strstr(request,HEADER_BG_PNG_PATH)) { data = HEADER_BG_PNG; data_size = HEADER_PNG_SIZE; } else if(strstr(request,FOOTER_BG_PNG_PATH)) { data = FOOTER_BG_PNG; data_size = FOOTER_BG_PNG_SIZE; } else if((strlen(request) == INDEX_PATH_SIZE) && (memcmp(request,INDEX_PATH,INDEX_PATH_SIZE) == 0)) { data = PROXY_HTML; data_size = PROXY_HTML_SIZE; } if(data) { /* Write data to browser */ if(send_http_response(csock,data,data_size) == SOCK_FAIL) { glog("Proxy server failed to write image data to client browser",LOG_ERROR_TYPE); return; } } else { /* Write client list to browser */ print_client_list(csock); } return; }
int ccnd_stats_handle_http_connection(struct ccnd_handle *h, struct face *face) { struct ccn_charbuf *response = NULL; char rbuf[16]; int i; int nspace; int n; ccnd_msg(h, "========== in ccnd_stats_handle_http_connection, face = %d", face); if (face->inbuf->length < 4) return(-1); if ((face->flags & CCN_FACE_NOSEND) != 0) { ccnd_destroy_face(h, face->faceid); return(-1); } ccnd_msg(h, "============ before n = sizeof(rbuf) - 1;"); n = sizeof(rbuf) - 1; if (face->inbuf->length < n) n = face->inbuf->length; for (i = 0, nspace = 0; i < n && nspace < 2; i++) { rbuf[i] = face->inbuf->buf[i]; if (rbuf[i] == ' ') nspace++; } ccnd_msg(h, "============= before rbuf[i] = 0;"); rbuf[i] = 0; if (nspace < 2 && i < sizeof(rbuf) - 1) return(-1); if (0 == strcmp(rbuf, "GET / ") || 0 == strcmp(rbuf, "GET /? ")) { ccnd_msg(h, "============== in 1 if"); response = collect_stats_html(h); ccnd_msg(h, "============== before send_http_response"); send_http_response(h, face, "text/html", response); } else if (0 == strcmp(rbuf, "GET /?l=none ")) { ccnd_msg(h, "============== in 2 else if"); ccnd_stats_http_set_debug(h, face, 0); } else if (0 == strcmp(rbuf, "GET /?l=low ")) { ccnd_msg(h, "============= in 3 else if"); ccnd_stats_http_set_debug(h, face, 1); } else if (0 == strcmp(rbuf, "GET /?l=co ")) { ccnd_msg(h, "============= in 4 else if"); ccnd_stats_http_set_debug(h, face, 4); } else if (0 == strcmp(rbuf, "GET /?l=med ")) { ccnd_msg(h, "============= in 5 else if"); ccnd_stats_http_set_debug(h, face, 71); } else if (0 == strcmp(rbuf, "GET /?l=high ")) { ccnd_msg(h, "============= in 6 else if"); ccnd_stats_http_set_debug(h, face, -1); } else if (0 == strcmp(rbuf, "GET /?f=xml ")) { ccnd_msg(h, "============= in 7 else if"); response = collect_stats_xml(h); send_http_response(h, face, "text/xml", response); } else if (0 == strcmp(rbuf, "GET ")){ ccnd_msg(h, "============= in 8 else if"); ccnd_send(h, face, resp404, strlen(resp404)); } else{ ccnd_msg(h, "============= in 9 else"); ccnd_send(h, face, resp405, strlen(resp405)); } face->flags |= (CCN_FACE_NOSEND | CCN_FACE_CLOSING); ccnd_msg(h, "=========== before ccn_charbuf_destroy(&response);"); ccn_charbuf_destroy(&response); return(0); }
void endpoint<connection,config>::send_http_response(connection_hdl hdl) { lib::error_code ec; send_http_response(hdl,ec); if (ec) { throw exception(ec); } }
/* process command to relay udp traffic * */ static int udp_relay( int sockfd, const char* param, size_t plen, const struct in_addr* mifaddr, struct server_ctx* ctx ) { char mcast_addr[ IPADDR_STR_SIZE ]; struct sockaddr_in addr; uint16_t port; pid_t new_pid; int rc = 0, flags; int msockfd = -1, sfilefd = -1, dfilefd = -1, srcfd = -1; char dfile_name[ MAXPATHLEN ]; size_t rcvbuf_len = 0; assert( (sockfd > 0) && param && plen && ctx ); TRACE( (void)tmfprintf( g_flog, "udp_relay : new_socket=[%d] param=[%s]\n", sockfd, param) ); do { rc = parse_udprelay( param, plen, mcast_addr, IPADDR_STR_SIZE, &port ); if( 0 != rc ) { (void) tmfprintf( g_flog, "Error [%d] parsing parameters [%s]\n", rc, param ); break; } if( 1 != inet_aton(mcast_addr, &addr.sin_addr) ) { (void) tmfprintf( g_flog, "Invalid address: [%s]\n", mcast_addr ); rc = ERR_INTERNAL; break; } addr.sin_family = AF_INET; addr.sin_port = htons( (short)port ); } while(0); if( 0 != rc ) { (void) send_http_response( sockfd, 500, "Service error" ); return rc; } /* start the (new) process to relay traffic */ if( 0 != (new_pid = fork()) ) { rc = add_client( ctx, new_pid, mcast_addr, port, sockfd ); return rc; /* parent returns */ } /* child process: */ TRACE( (void)tmfprintf( g_flog, "Client process=[%d] started " "for socket=[%d]\n", getpid(), sockfd) ); (void) get_pidstr( PID_RESET, "c" ); (void)close( ctx->lsockfd ); /* close the reading end of the comm. pipe */ (void)close( ctx->cpipe[0] ); ctx->cpipe[0] = -1; do { /* make write end of pipe non-blocking (we don't want to * block on pipe write while relaying traffic) */ if( -1 == (flags = fcntl( ctx->cpipe[1], F_GETFL )) || -1 == fcntl( ctx->cpipe[1], F_SETFL, flags | O_NONBLOCK ) ) { mperror( g_flog, errno, "%s: fcntl", __func__ ); rc = -1; break; } if( NULL != g_uopt.dstfile ) { (void) snprintf( dfile_name, MAXPATHLEN - 1, "%s.%d", g_uopt.dstfile, getpid() ); dfilefd = creat( dfile_name, S_IRUSR | S_IWUSR | S_IRGRP ); if( -1 == dfilefd ) { mperror( g_flog, errno, "%s: g_uopt.dstfile open", __func__ ); rc = -1; break; } TRACE( (void)tmfprintf( g_flog, "Dest file [%s] opened as fd=[%d]\n", dfile_name, dfilefd ) ); } else dfilefd = -1; if( NULL != g_uopt.srcfile ) { sfilefd = open( g_uopt.srcfile, O_RDONLY | O_NOCTTY ); if( -1 == sfilefd ) { mperror( g_flog, errno, "%s: g_uopt.srcfile open", __func__ ); rc = -1; } else { TRACE( (void) tmfprintf( g_flog, "Source file [%s] opened\n", g_uopt.srcfile ) ); srcfd = sfilefd; } } else { rc = calc_buf_settings( NULL, &rcvbuf_len ); if (0 == rc ) { rc = setup_mcast_listener( &addr, mifaddr, &msockfd, (g_uopt.nosync_sbuf ? 0 : rcvbuf_len) ); srcfd = msockfd; } } if( 0 != rc ) break; rc = relay_traffic( srcfd, sockfd, ctx, dfilefd, mifaddr ); if( 0 != rc ) break; } while(0); if( msockfd > 0 ) { close_mcast_listener( msockfd, mifaddr ); } if( sfilefd > 0 ) { (void) close( sfilefd ); TRACE( (void) tmfprintf( g_flog, "Source file [%s] closed\n", g_uopt.srcfile ) ); } if( dfilefd > 0 ) { (void) close( dfilefd ); TRACE( (void) tmfprintf( g_flog, "Dest file [%s] closed\n", dfile_name ) ); } if( 0 != rc ) { (void) send_http_response( sockfd, 500, "Service error" ); } (void) close( sockfd ); free_server_ctx( ctx ); closelog(); TRACE( (void)tmfprintf( g_flog, "Child process=[%d] exits with rc=[%d]\n", getpid(), rc) ); if( g_flog && (stderr != g_flog) ) { (void) fclose(g_flog); } free_uopt( &g_uopt ); rc = ( 0 != rc ) ? ERR_INTERNAL : rc; exit(rc); /* child exits */ return rc; }
/* relay traffic from source to destination socket * */ static int relay_traffic( int ssockfd, int dsockfd, struct server_ctx* ctx, int dfilefd, const struct in_addr* mifaddr ) { volatile sig_atomic_t quit = 0; int rc = 0; ssize_t nmsgs = -1; ssize_t nrcv = 0, nsent = 0, nwr = 0, lrcv = 0, lsent = 0; char* data = NULL; size_t data_len = g_uopt.rbuf_len; struct rdata_opt ropt; time_t pause_time = 0, rfr_tm = time(NULL); sigset_t ubset; const int ALLOW_PAUSES = get_flagval( "UDPXY_ALLOW_PAUSES", 0 ); const ssize_t MAX_PAUSE_MSEC = get_sizeval( "UDPXY_PAUSE_MSEC", 1000); /* permissible variation in data-packet size */ static const ssize_t t_delta = 0x20; struct dstream_ctx ds; static const int SET_PID = 1; struct tps_data tps; assert( ctx && mifaddr && MAX_PAUSE_MSEC > 0 ); (void) sigemptyset (&ubset); sigaddset (&ubset, SIGINT); sigaddset (&ubset, SIGQUIT); sigaddset (&ubset, SIGTERM); /* restore the ability to receive *quit* signals */ rc = sigprocmask (SIG_UNBLOCK, &ubset, NULL); if (0 != rc) { mperror (g_flog, errno, "%s: sigprocmask", __func__); return -1; } /* NOPs to eliminate warnings in lean version */ (void)&lrcv; (void)&lsent; (void)&t_delta; check_fragments( NULL, 0, 0, 0, 0, g_flog ); /* INIT */ rc = calc_buf_settings( &nmsgs, NULL ); if (0 != rc) return -1; TRACE( (void)tmfprintf( g_flog, "Data buffer will hold up to " "[%d] messages\n", nmsgs ) ); rc = init_dstream_ctx( &ds, ctx->cmd, g_uopt.srcfile, nmsgs ); if( 0 != rc ) return -1; (void) set_nice( g_uopt.nice_incr, g_flog ); do { if( NULL == g_uopt.srcfile ) { rc = set_timeouts( ssockfd, dsockfd, ctx->rcv_tmout, 0, ctx->snd_tmout, 0 ); if( 0 != rc ) break; } if( dsockfd > 0 ) { rc = sync_dsockbuf_len( ssockfd, dsockfd ); if( 0 != rc ) break; rc = send_http_response( dsockfd, 200, "OK" ); if( 0 != rc ) break; /* timeshift: to detect PAUSE make destination * socket non-blocking, otherwise make it blocking * (since it might have been set unblocking earlier) */ rc = set_nblock( dsockfd, (ALLOW_PAUSES ? 1 : 0) ); if( 0 != rc ) break; } data = malloc(data_len); if( NULL == data ) { mperror( g_flog, errno, "%s: malloc", __func__ ); break; } if( g_uopt.cl_tpstat ) tpstat_init( &tps, SET_PID ); } while(0); TRACE( (void)tmfprintf( g_flog, "Relaying traffic from socket[%d] " "to socket[%d], buffer size=[%d], Rmsgs=[%d], pauses=[%d]\n", ssockfd, dsockfd, data_len, g_uopt.rbuf_msgs, ALLOW_PAUSES) ); /* RELAY LOOP */ ropt.max_frgs = g_uopt.rbuf_msgs; ropt.buf_tmout = g_uopt.dhold_tmout; pause_time = 0; while( (0 == rc) && !(quit = must_quit()) ) { if( g_uopt.mcast_refresh > 0 ) { check_mcast_refresh( ssockfd, &rfr_tm, mifaddr ); } nrcv = read_data( &ds, ssockfd, data, data_len, &ropt ); if( -1 == nrcv ) break; TRACE( check_fragments( "received new", data_len, lrcv, nrcv, t_delta, g_flog ) ); lrcv = nrcv; if( dsockfd && (nrcv > 0) ) { nsent = write_data( &ds, data, nrcv, dsockfd ); if( -1 == nsent ) break; if ( nsent < 0 ) { if ( !ALLOW_PAUSES ) break; if ( 0 != pause_detect( nsent, MAX_PAUSE_MSEC, &pause_time ) ) break; } TRACE( check_fragments("sent", nrcv, lsent, nsent, t_delta, g_flog) ); lsent = nsent; } if( (dfilefd > 0) && (nrcv > 0) ) { nwr = write_data( &ds, data, nrcv, dfilefd ); if( -1 == nwr ) break; TRACE( check_fragments( "wrote to file", nrcv, lsent, nwr, t_delta, g_flog ) ); lsent = nwr; } if( ds.flags & F_SCATTERED ) reset_pkt_registry( &ds ); if( uf_TRUE == g_uopt.cl_tpstat ) tpstat_update( ctx, &tps, nsent ); } /* end of RELAY LOOP */ /* CLEANUP */ TRACE( (void)tmfprintf( g_flog, "Exited relay loop: received=[%ld], " "sent=[%ld], quit=[%ld]\n", (long)nrcv, (long)nsent, (long)quit ) ); free_dstream_ctx( &ds ); if( NULL != data ) free( data ); if( 0 != (quit = must_quit()) ) { TRACE( (void)tmfprintf( g_flog, "Child process=[%d] must quit\n", getpid()) ); } return rc; }