int main(int argc, char *argv[]) { struct sockaddr_in me; #ifdef ENABLE_IPV6 struct sockaddr_in6 me6; #endif /* ENABLE_IPV6 */ curl_socket_t sock = CURL_SOCKET_BAD; curl_socket_t msgsock = CURL_SOCKET_BAD; int wrotepidfile = 0; int flag; unsigned short port = DEFAULT_PORT; char *pidname= (char *)".rtsp.pid"; struct httprequest req; int rc; int error; int arg=1; long pid; while(argc>arg) { if(!strcmp("--version", argv[arg])) { printf("rtspd IPv4%s" "\n" , #ifdef ENABLE_IPV6 "/IPv6" #else "" #endif ); return 0; } else if(!strcmp("--pidfile", argv[arg])) { arg++; if(argc>arg) pidname = argv[arg++]; } else if(!strcmp("--logfile", argv[arg])) { arg++; if(argc>arg) serverlogfile = argv[arg++]; } else if(!strcmp("--ipv4", argv[arg])) { #ifdef ENABLE_IPV6 ipv_inuse = "IPv4"; use_ipv6 = FALSE; #endif arg++; } else if(!strcmp("--ipv6", argv[arg])) { #ifdef ENABLE_IPV6 ipv_inuse = "IPv6"; use_ipv6 = TRUE; #endif arg++; } else if(!strcmp("--port", argv[arg])) { arg++; if(argc>arg) { char *endptr; long lnum = -1; lnum = strtol(argv[arg], &endptr, 10); if((endptr != argv[arg] + strlen(argv[arg])) || (lnum < 1025L) || (lnum > 65535L)) { fprintf(stderr, "rtspd: invalid --port argument (%s)\n", argv[arg]); return 0; } port = (unsigned short)(lnum & 0xFFFFL); arg++; } } else if(!strcmp("--srcdir", argv[arg])) { arg++; if(argc>arg) { path = argv[arg]; arg++; } } else { puts("Usage: rtspd [option]\n" " --version\n" " --logfile [file]\n" " --pidfile [file]\n" " --ipv4\n" " --ipv6\n" " --port [port]\n" " --srcdir [path]"); return 0; } } #ifdef WIN32 win32_init(); atexit(win32_cleanup); #endif install_signal_handlers(); pid = (long)getpid(); #ifdef ENABLE_IPV6 if(!use_ipv6) #endif sock = socket(AF_INET, SOCK_STREAM, 0); #ifdef ENABLE_IPV6 else sock = socket(AF_INET6, SOCK_STREAM, 0); #endif if(CURL_SOCKET_BAD == sock) { error = SOCKERRNO; logmsg("Error creating socket: (%d) %s", error, strerror(error)); goto server_cleanup; } flag = 1; if (0 != setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&flag, sizeof(flag))) { error = SOCKERRNO; logmsg("setsockopt(SO_REUSEADDR) failed with error: (%d) %s", error, strerror(error)); goto server_cleanup; } #ifdef ENABLE_IPV6 if(!use_ipv6) { #endif memset(&me, 0, sizeof(me)); me.sin_family = AF_INET; me.sin_addr.s_addr = INADDR_ANY; me.sin_port = htons(port); rc = bind(sock, (struct sockaddr *) &me, sizeof(me)); #ifdef ENABLE_IPV6 } else { memset(&me6, 0, sizeof(me6)); me6.sin6_family = AF_INET6; me6.sin6_addr = in6addr_any; me6.sin6_port = htons(port); rc = bind(sock, (struct sockaddr *) &me6, sizeof(me6)); } #endif /* ENABLE_IPV6 */ if(0 != rc) { error = SOCKERRNO; logmsg("Error binding socket on port %hu: (%d) %s", port, error, strerror(error)); goto server_cleanup; } logmsg("Running %s version on port %d", ipv_inuse, (int)port); /* start accepting connections */ rc = listen(sock, 5); if(0 != rc) { error = SOCKERRNO; logmsg("listen() failed with error: (%d) %s", error, strerror(error)); goto server_cleanup; } /* ** As soon as this server writes its pid file the test harness will ** attempt to connect to this server and initiate its verification. */ wrotepidfile = write_pidfile(pidname); if(!wrotepidfile) goto server_cleanup; for (;;) { msgsock = accept(sock, NULL, NULL); if(got_exit_signal) break; if (CURL_SOCKET_BAD == msgsock) { error = SOCKERRNO; logmsg("MAJOR ERROR: accept() failed with error: (%d) %s", error, strerror(error)); break; } /* ** As soon as this server acepts a connection from the test harness it ** must set the server logs advisor read lock to indicate that server ** logs should not be read until this lock is removed by this server. */ set_advisor_read_lock(SERVERLOGS_LOCK); serverlogslocked = 1; logmsg("====> Client connect"); #ifdef TCP_NODELAY /* * Disable the Nagle algorithm to make it easier to send out a large * response in many small segments to torture the clients more. */ flag = 1; if (setsockopt(msgsock, IPPROTO_TCP, TCP_NODELAY, (void *)&flag, sizeof(flag)) == -1) { logmsg("====> TCP_NODELAY failed"); } #endif /* initialization of httprequest struct is done in get_request(), but due to pipelining treatment the pipelining struct field must be initialized previously to FALSE every time a new connection arrives. */ req.pipelining = FALSE; do { if(got_exit_signal) break; if(get_request(msgsock, &req)) /* non-zero means error, break out of loop */ break; if(prevbounce) { /* bounce treatment requested */ if((req.testno == prevtestno) && (req.partno == prevpartno)) { req.partno++; logmsg("BOUNCE part number to %ld", req.partno); } else { prevbounce = FALSE; prevtestno = -1; prevpartno = -1; } } send_doc(msgsock, &req); if(got_exit_signal) break; if((req.testno < 0) && (req.testno != DOCNUMBER_CONNECT)) { logmsg("special request received, no persistency"); break; } if(!req.open) { logmsg("instructed to close connection after server-reply"); break; } if(req.open) logmsg("=> persistant connection request ended, awaits new request"); /* if we got a CONNECT, loop and get another request as well! */ } while(req.open || (req.testno == DOCNUMBER_CONNECT)); if(got_exit_signal) break; logmsg("====> Client disconnect"); sclose(msgsock); msgsock = CURL_SOCKET_BAD; if(serverlogslocked) { serverlogslocked = 0; clear_advisor_read_lock(SERVERLOGS_LOCK); } if (req.testno == DOCNUMBER_QUIT) break; } server_cleanup: if((msgsock != sock) && (msgsock != CURL_SOCKET_BAD)) sclose(msgsock); if(sock != CURL_SOCKET_BAD) sclose(sock); if(got_exit_signal) logmsg("signalled to die"); if(wrotepidfile) unlink(pidname); if(serverlogslocked) { serverlogslocked = 0; clear_advisor_read_lock(SERVERLOGS_LOCK); } restore_signal_handlers(); if(got_exit_signal) { logmsg("========> %s rtspd (port: %d pid: %ld) exits with signal (%d)", ipv_inuse, (int)port, pid, exit_signal); /* * To properly set the return status of the process we * must raise the same signal SIGINT or SIGTERM that we * caught and let the old handler take care of it. */ raise(exit_signal); } logmsg("========> rtspd quits"); return 0; }
int main(int argc, char *argv[]) { struct sockaddr_in me; int sock, msgsock, flag; unsigned short port = DEFAULT_PORT; char *logfile = DEFAULT_LOGFILE; int part_no; FILE *pidfile; if(argc>1) port = atoi(argv[1]); /* FIX: write our pid to a file name */ logfp = fopen(logfile, "a"); if (!logfp) { perror(logfile); exit(1); } #ifdef HAVE_SIGNAL /* FIX: make a more portable signal handler */ signal(SIGPIPE, sigpipe_handler); signal(SIGINT, sigterm_handler); signal(SIGTERM, sigterm_handler); siginterrupt(SIGPIPE, 1); siginterrupt(SIGINT, 1); siginterrupt(SIGTERM, 1); #endif sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("opening stream socket"); fprintf(logfp, "Error opening socket -- aborting\n"); fclose(logfp); exit(1); } flag = 1; if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &flag, sizeof(int)) < 0) { perror("setsockopt(SO_REUSEADDR)"); } me.sin_family = AF_INET; me.sin_addr.s_addr = INADDR_ANY; me.sin_port = htons(port); if (bind(sock, (struct sockaddr *) &me, sizeof me) < 0) { perror("binding stream socket"); fprintf(logfp, "Error binding socket -- aborting\n"); fclose(logfp); exit(1); } pidfile = fopen(".http.pid", "w"); if(pidfile) { fprintf(pidfile, "%d\n", (int)getpid()); fclose(pidfile); } else fprintf(stderr, "Couldn't write pid file\n"); /* start accepting connections */ listen(sock, 5); fprintf(stderr, "*** %s listening on port %u ***\n", VERSION, port); while (!sigterm) { int doc; msgsock = accept(sock, NULL, NULL); if (msgsock == -1) { if (sigterm) { break; } /* perror("accept"); */ continue; } logmsg("New client connected"); doc = get_request(msgsock, &part_no); send_doc(msgsock, doc, part_no); close(msgsock); } close(sock); fclose(logfp); return 0; }
int main(int argc, char *argv[]) { struct sockaddr_in me; #ifdef ENABLE_IPV6 struct sockaddr_in6 me6; #endif /* ENABLE_IPV6 */ curl_socket_t sock, msgsock; int flag; unsigned short port = DEFAULT_PORT; char *pidname= (char *)".http.pid"; struct httprequest req; int rc; int arg=1; #ifdef CURL_SWS_FORK_ENABLED bool use_fork = FALSE; #endif while(argc>arg) { if(!strcmp("--version", argv[arg])) { printf("sws IPv4%s" #ifdef CURL_SWS_FORK_ENABLED " FORK" #endif "\n" , #ifdef ENABLE_IPV6 "/IPv6" #else "" #endif ); return 0; } else if(!strcmp("--pidfile", argv[arg])) { arg++; if(argc>arg) pidname = argv[arg++]; } else if(!strcmp("--ipv6", argv[arg])) { #ifdef ENABLE_IPV6 use_ipv6=TRUE; #endif arg++; } #ifdef CURL_SWS_FORK_ENABLED else if(!strcmp("--fork", argv[arg])) { use_fork=TRUE; arg++; } #endif else if(argc>arg) { if(atoi(argv[arg])) port = (unsigned short)atoi(argv[arg++]); if(argc>arg) path = argv[arg++]; } } #ifdef WIN32 win32_init(); atexit(win32_cleanup); #else #ifdef SIGPIPE #ifdef HAVE_SIGNAL signal(SIGPIPE, sigpipe_handler); #endif #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGPIPE, 1); #endif #endif #endif #ifdef ENABLE_IPV6 if(!use_ipv6) #endif sock = socket(AF_INET, SOCK_STREAM, 0); #ifdef ENABLE_IPV6 else sock = socket(AF_INET6, SOCK_STREAM, 0); #endif if (CURL_SOCKET_BAD == sock) { logmsg("Error opening socket: %d", SOCKERRNO); return 1; } flag = 1; if (0 != setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &flag, sizeof(flag))) { logmsg("setsockopt(SO_REUSEADDR) failed: %d", SOCKERRNO); sclose(sock); return 1; } #ifdef ENABLE_IPV6 if(!use_ipv6) { #endif memset(&me, 0, sizeof(me)); me.sin_family = AF_INET; me.sin_addr.s_addr = INADDR_ANY; me.sin_port = htons(port); rc = bind(sock, (struct sockaddr *) &me, sizeof(me)); #ifdef ENABLE_IPV6 } else { memset(&me6, 0, sizeof(me6)); me6.sin6_family = AF_INET6; me6.sin6_addr = in6addr_any; me6.sin6_port = htons(port); rc = bind(sock, (struct sockaddr *) &me6, sizeof(me6)); } #endif /* ENABLE_IPV6 */ if(0 != rc) { logmsg("Error binding socket: %d", SOCKERRNO); sclose(sock); return 1; } if(!write_pidfile(pidname)) { sclose(sock); return 1; } logmsg("Running IPv%d version on port %d", #ifdef ENABLE_IPV6 (use_ipv6?6:4) #else 4 #endif , port ); /* start accepting connections */ rc = listen(sock, 5); if(0 != rc) { logmsg("listen() failed with error: %d", SOCKERRNO); sclose(sock); return 1; } while (1) { msgsock = accept(sock, NULL, NULL); if (CURL_SOCKET_BAD == msgsock) { printf("MAJOR ERROR: accept() failed with error: %d\n", SOCKERRNO); break; } #ifdef CURL_SWS_FORK_ENABLED if(use_fork) { /* The fork enabled version just forks off the child and don't care about it anymore, so don't assume otherwise. Beware and don't do this at home. */ rc = fork(); if(-1 == rc) { printf("MAJOR ERROR: fork() failed!\n"); break; } } else /* not a fork, just set rc so the following proceeds nicely */ rc = 0; /* 0 is returned to the child */ if(0 == rc) { #endif logmsg("====> Client connect"); #ifdef TCP_NODELAY /* * Disable the Nagle algorithm to make it easier to send out a large * response in many small segments to torture the clients more. */ flag = 1; if (setsockopt(msgsock, IPPROTO_TCP, TCP_NODELAY, (void *)&flag, sizeof(flag)) == -1) { logmsg("====> TCP_NODELAY failed"); } #endif /* initialization of httprequest struct is done in get_request(), but due to pipelining treatment the pipelining struct field must be initialized previously to FALSE every time a new connection arrives. */ req.pipelining = FALSE; do { if(get_request(msgsock, &req)) /* non-zero means error, break out of loop */ break; if(prevbounce) { /* bounce treatment requested */ if((req.testno == prevtestno) && (req.partno == prevpartno)) { req.partno++; logmsg("BOUNCE part number to %ld", req.partno); } else { prevbounce = FALSE; prevtestno = -1; prevpartno = -1; } } send_doc(msgsock, &req); if((req.testno < 0) && (req.testno != DOCNUMBER_CONNECT)) { logmsg("special request received, no persistancy"); break; } if(!req.open) { logmsg("instructed to close connection after server-reply"); break; } if(req.open) logmsg("=> persistant connection request ended, awaits new request"); /* if we got a CONNECT, loop and get another request as well! */ } while(req.open || (req.testno == DOCNUMBER_CONNECT)); logmsg("====> Client disconnect"); sclose(msgsock); if (req.testno == DOCNUMBER_QUIT) break; #ifdef CURL_SWS_FORK_ENABLED } #endif } sclose(sock); return 0; }
int main(int argc, char *argv[]) { struct sockaddr_in me; #ifdef ENABLE_IPV6 struct sockaddr_in6 me6; #endif /* ENABLE_IPV6 */ int sock, msgsock, flag; unsigned short port = DEFAULT_PORT; FILE *pidfile; char *pidname= (char *)".http.pid"; struct httprequest req; int rc; int arg=1; while(argc>arg) { if(!strcmp("--version", argv[arg])) { printf("sws IPv4%s\n", #ifdef ENABLE_IPV6 "/IPv6" #else "" #endif ); return 0; } else if(!strcmp("--pidfile", argv[arg])) { arg++; if(argc>arg) pidname = argv[arg++]; } else if(!strcmp("--ipv6", argv[arg])) { #ifdef ENABLE_IPV6 use_ipv6=TRUE; #endif arg++; } else if(argc>arg) { if(atoi(argv[arg])) port = (unsigned short)atoi(argv[arg++]); if(argc>arg) path = argv[arg++]; } } #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) win32_init(); atexit(win32_cleanup); #else #ifdef SIGPIPE #ifdef HAVE_SIGNAL signal(SIGPIPE, sigpipe_handler); #endif #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGPIPE, 1); #endif #endif #endif #ifdef ENABLE_IPV6 if(!use_ipv6) #endif sock = socket(AF_INET, SOCK_STREAM, 0); #ifdef ENABLE_IPV6 else sock = socket(AF_INET6, SOCK_STREAM, 0); #endif if (sock < 0) { perror("opening stream socket"); logmsg("Error opening socket"); exit(1); } flag = 1; if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &flag, sizeof(int)) < 0) { perror("setsockopt(SO_REUSEADDR)"); } #ifdef ENABLE_IPV6 if(!use_ipv6) { #endif me.sin_family = AF_INET; me.sin_addr.s_addr = INADDR_ANY; me.sin_port = htons(port); rc = bind(sock, (struct sockaddr *) &me, sizeof(me)); #ifdef ENABLE_IPV6 } else { memset(&me6, 0, sizeof(struct sockaddr_in6)); me6.sin6_family = AF_INET6; me6.sin6_addr = in6addr_any; me6.sin6_port = htons(port); rc = bind(sock, (struct sockaddr *) &me6, sizeof(me6)); } #endif /* ENABLE_IPV6 */ if(rc < 0) { perror("binding stream socket"); logmsg("Error binding socket"); exit(1); } pidfile = fopen(pidname, "w"); if(pidfile) { fprintf(pidfile, "%d\n", (int)getpid()); fclose(pidfile); } else fprintf(stderr, "Couldn't write pid file\n"); logmsg("Running IPv%d version on port %d", #ifdef ENABLE_IPV6 (use_ipv6?6:4) #else 4 #endif , port ); /* start accepting connections */ listen(sock, 5); while (1) { msgsock = accept(sock, NULL, NULL); if (msgsock == -1) continue; logmsg("====> Client connect"); do { if(get_request(msgsock, &req)) /* non-zero means error, break out of loop */ break; if(prevbounce) { /* bounce treatment requested */ if((req.testno == prevtestno) && (req.partno == prevpartno)) { req.partno++; logmsg("BOUNCE part number to %ld", req.partno); } } send_doc(msgsock, &req); if((req.testno < 0) && (req.testno != DOCNUMBER_CONNECT)) { logmsg("special request received, no persistancy"); break; } if(!req.open) { logmsg("instructed to close connection after server-reply"); break; } if(req.open) logmsg("=> persistant connection request ended, awaits new request"); /* if we got a CONNECT, loop and get another request as well! */ } while(req.open || (req.testno == DOCNUMBER_CONNECT)); logmsg("====> Client disconnect"); sclose(msgsock); if (req.testno == DOCNUMBER_QUIT) break; } sclose(sock); return 0; }