/* * main(): This function is the entry point for the server program of Share Your Playlist application. * This function creates the upload and download sockets and waits for client connections. * We have implemented all the 3 methods used in concurrency in servers namely: * 1. Multi-process approach using fork() for handling upload and download functionalities * 2. Non-blocking I/O using select() for monitoring two ports on server * 3. Multi-threaded approach for data redundancy between servers */ int main(int argc, char **argv) { struct sockaddr_in sockserv; unsigned int alen; int upload_sock, download_sock, i, slave_sock, fds[2], *fd = NULL; struct sockaddr *addr; socklen_t *addrlen; //binds sockets for upload and download functionality upload_sock = passiveTCP(UPLOAD_PORT); download_sock = passiveTCP(DOWNLOAD_PORT); printf("Upload sock : %d\n", upload_sock); printf("Download sock : %d\n", download_sock); fds[0] = upload_sock; fds[1] = download_sock; while (1) { //calls function to identify which port client connected to slave_sock = network_accept_any(fds, 2, &fd); //Initializing thread attributes for prstats thread (void) pthread_attr_init(&ta); (void) pthread_attr_setdetachstate(&ta, PTHREAD_CREATE_DETACHED); (void) pthread_mutex_init(&stats.st_mutex, 0); /*if(pthread_create(&th, &ta, (void * (*)(void *))prstats, 0) < 0) fatal("prstats thread failed");*/ //Based on socket that obtained the connection, we use multi-process approach using fork() to provide concurrency //Based on upload/download, the respective functions are called in the child processes. if (*fd == upload_sock) { switch (fork()) { case 0: close(*fd); exit(handleUpload(slave_sock)); default: close(slave_sock); break; } } if (*fd == download_sock) { switch (fork()) { case 0: close(*fd); exit(handleDownload(slave_sock)); default: close(slave_sock); break; } } } }
/*------------------------------------------------------------------------ * main - Concurrent TCP server for browse_file_system service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { char *service = get_port(); /* service name or port number */ struct sockaddr_in fsin; /* the address of a client */ int alen; /* length of client's address */ int msock; /* master server socket */ int ssock; /* slave server socket */ switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("too many arguments...\n"); } msock = passiveTCP(service, QLEN); // reaper (void) signal(SIGCHLD, reaper); // fork() creates a new process by duplicating the calling process. // The new process, referred to as the child, is an exact duplicate of // the calling process, referred to as the parent... // On success, the PID of the child process is returned in the parent, // and 0 is returned in the child. On failure, -1 is returned in the parent, switch (fork()) { case 0: /* child */ fork(); default: /* parent */ break; case -1: errexit("fork: %s\n", strerror(errno)); } // end switch while (1) // handle one client request per iteration. { alen = sizeof(fsin); // accept a client, get slave socket connected to that client. ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) { if (errno == EINTR) continue; errexit("accept: %s\n", strerror(errno)); } else { TCPbrowser(ssock); close(ssock); printf("im dead\n"); } } // end while loop } // end main
/*------------------------------------------------------------------------ * main - Iterative TCP server for DAYTIME service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { struct sockaddr_in fsin; /* the from address of a client */ char *service = "daytime"; /* service name or port number */ int msock, ssock; /* master & slave sockets */ unsigned int alen; /* from-address length */ switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPdaytimed [port]\n"); } msock = passiveTCP(service, QLEN); int fid; while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) errexit("accept failed: %s\n", strerror(errno)); else { if (fid = fork() == 0 ){ TCPdaytimed(ssock); (void) close(ssock); } } } }
int main(int argc, char *argv[]) { struct sockaddr_in fsin; /* the from address of a client */ char *service = get_port(); /* service name or port number */ int msock, ssock; /* master & slave sockets */ int alen; /* from-address length */ switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("<klaxon>\n"); } msock = passiveTCP(service, QLEN); while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) errexit("accept failed: %s\n", strerror(errno)); (void) Ttimed(ssock); (void) close(ssock); } }
int main(int argc, char *arg[]) { char buffer[256]; struct sockaddr_in6 fsin; char *service = "daytime"; int msock, ssock; int alen,pid; msock = passiveTCP(service, QLEN); while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) { printf("Error in accepting the socket connection\n"); exit(0); } pid=fork(); if(pid==0) { printf("This is a new client request\n"); close(msock); TCPdaytimed(ssock); exit(0); } } close(ssock); }
int main() { int msock, ssock, pid, clilen, cmd; struct sockaddr_in client_addr; char *service = "ftp"; pthread_t th; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); msock = passiveTCP(service, QLEN); clilen = sizeof(client_addr); while(1) { /* ACCEPT A CONNECTION AND THEN CREATE A CHILD TO DO THE WORK */ /* LOOP BACK AND WAIT FOR ANOTHER CONNECTION */ printf("server: starting accept\n"); ssock = accept(msock ,(struct sockaddr *) &client_addr, &clilen); if (ssock < 0) { printf("server: accept error: %d\n", errno); exit(1); } if (pthread_create(&th, &attr, doftp, (void *)(long)ssock)) { printf("server: pthread_create error: %s\n", strerror(errno)); exit(1); } } }
/*------------------------------------------------------------------------ * main - Iterative server for DAYTIME service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { char *service = "daytime"; /* service name or port number */ char buf[LINELEN+1]; /* buffer for one line of text */ struct sockaddr_in fsin; /* the request from address */ int alen; /* from-address length */ int tsock; /* TCP master socket */ int usock; /* UDP socket */ int nfds; fd_set rfds; /* readable file descriptors */ switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: daytimed [port]\n"); } tsock = passiveTCP(service, QLEN); usock = passiveUDP(service); nfds = MAX(tsock, usock) + 1; /* bit number of max fd */ FD_ZERO(&rfds); while (1) { FD_SET(tsock, &rfds); FD_SET(usock, &rfds); if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) errexit("select error: %s\n", strerror(errno)); if (FD_ISSET(tsock, &rfds)) { int ssock; /* TCP slave socket */ alen = sizeof(fsin); ssock = accept(tsock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) errexit("accept failed: %s\n", strerror(errno)); daytime(buf); (void) write(ssock, buf, strlen(buf)); (void) close(ssock); } if (FD_ISSET(usock, &rfds)) { alen = sizeof(fsin); if (recvfrom(usock, buf, sizeof(buf), 0, (struct sockaddr *)&fsin, &alen) < 0) errexit("recvfrom: %s\n", strerror(errno)); daytime(buf); (void) sendto(usock, buf, strlen(buf), 0, (struct sockaddr *)&fsin, sizeof(fsin)); } } }
int main() { int msock, sel; char *service = "ftp"; enum selection option; printf("Please enter number to select corresponding option:\n"); printf("0: select\n1:fork\n2:thread\n"); scanf("%d", &sel); option = sel; msock = passiveTCP(service, QLEN); switch(option) { case SELECT: printf("SELECT option was selected\n"); do_select(msock); break; case FORK: printf("FORK option was selected\n"); do_fork(msock); break; case THREAD: printf("THREAD option was selected\n"); do_thread(msock); break; default: printf("Invalid option\n"); exit(1); } }
int main(int argc, char *argv[]) { int csd; /* client & server socket descriptors */ char *service="12345"; /* service name or port number --default value */ struct sockaddr_in cli_addr; /* the address of a client */ unsigned int size; /* length of client's address */ //struct sockaddr_in serv_addr; struct sigaction sa; pthread_t *threads; switch (argc) //switch case to properly check the command line arguments { case 1: break; //to be removed after case 2: service = argv[1]; //assigning the service value given by user. break; default: set_output_error_color(); printf("usage: td <port>\n"); set_output_default_color(); exit(1); } printf("%s", "Server is beginning...\n"); //call this routine to create socket. ssd = passiveTCP(service, QLEN); //create slave socket descriptor /* sa.sa_handler = sig_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if(sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); }*/ //have to dig through while(1) { size = sizeof(cli_addr); printf("Waiting for the CLIENT connections...\n"); if((csd=accept(ssd,(struct sockaddr*)&cli_addr,&size))==-1) { perror("accept"); continue; } printf("server: Connection recvd from %s\n",inet_ntoa(cli_addr.sin_addr)); threads=(pthread_t *)malloc(sizeof(pthread_t)); if(pthread_create(threads,NULL,telnetSession,(void*)&csd)!=0) perror("pthread_create"); //start the Telnet session //telnetSession(csd,ssd); //start the Telnet session //if(close(csd) <0) //close the Client socket descriptor // perror("close:"); }// end of while(1) return 0; }//end of MAIN()
/*------------------------------------------------------------------------ * main - Concurrent TCP server for ECHO service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { pthread_t th; pthread_attr_t ta; /*char *service = "echo"; /* service name or port number */ char *service = "10000"; struct sockaddr_in fsin,cli; /* the address of a client */ unsigned int alen,clen; /* length of client's address */ int msock; /* master server socket */ int ssock; /* slave server socket */ char buff[BUFSIZE]; /*switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPechod [port]\n"); }*/ msock = passiveTCP(service, QLEN); (void) pthread_attr_init(&ta); (void) pthread_attr_setdetachstate(&ta, PTHREAD_CREATE_DETACHED); (void) pthread_mutex_init(&stats.st_mutex, 0); if (pthread_create(&th, &ta, (void * (*)(void *))prstats, 0) < 0) errexit("pthread_create(prstats): %s\n", strerror(errno)); while (1) { alen = sizeof(fsin); clen = sizeof(cli); //ssock = accept(msock, (struct sockaddr *)&fsin, &alen); ssock = accept(msock, (struct sockaddr *)&cli, &clen); //fsin.sin_addr.s_addr=htonl(fsin.sin_addr.s_addr); //inet_ntoa(adr_inet.sin_addr) //(struct sockaddr *)&fsin, &alen) //printf("connection from %d, port %d\n", // Inet_ntop(AF_INET, &cli.sin_addr, buff, sizeof(buff)), ntohs(cli.sin_port)); //getpeername(ssock,(struct sockaddr *)&fsin, &alen); //(void) printf("%d\n", getpeername(ssock,(struct sockaddr *)&nm, &nlen)); //(void) printf("%s\n", inet_ntoa(addr.sin_addr)); //(void) printf("%lu\n", fsin.sin_addr.s_addr); //fsin.sa_data sin_addr //inet_ntoa((struct sockaddr *)&fsin.sa_data) if (ssock < 0) { if (errno == EINTR) continue; errexit("accept: %s\n", strerror(errno)); } if (pthread_create(&th, &ta, (void * (*)(void *))TCPechod, (void *)ssock) < 0) errexit("pthread_create: %s\n", strerror(errno)); } }
/*------------------------------------------------------------------------ * main - Concurrent TCP server for ECHO service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { char *service = "echo"; /* service name or port number */ struct sockaddr_in fsin; /* the from address of a client */ int msock; /* master server socket */ fd_set rfds; /* read file descriptor set */ fd_set afds; /* active file descriptor set */ unsigned int alen; /* from-address length */ int fd, nfds; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPmechod [port]\n"); } msock = passiveTCP(service, QLEN); nfds = getdtablesize(); FD_ZERO(&afds); FD_SET(msock, &afds); while (1) { memcpy(&rfds, &afds, sizeof(rfds)); if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) errexit("select: %s\n", strerror(errno)); if (FD_ISSET(msock, &rfds)) { int ssock; alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) errexit("accept: %s\n", strerror(errno)); FD_SET(ssock, &afds); } for (fd=0; fd<nfds; ++fd) if (fd != msock && FD_ISSET(fd, &rfds)) if (echo(fd) == 0) { (void) close(fd); FD_CLR(fd, &afds); } } }
/*------------------------------------------------------------------------ * main - Super-server main program *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { struct service *psv, /* service table pointer */ *fd2sv[NOFILE]; /* map fd to service pointer */ int fd, nfds; fd_set afds, rfds; /* readable file descriptors */ switch (argc) { case 1: break; case 2: portbase = (u_short) atoi(argv[1]); break; default: errexit("usage: superd [portbase]\n"); } nfds = 0; FD_ZERO(&afds); for (psv = &svent[0]; psv->sv_name; ++psv) { if (psv->sv_useTCP) psv->sv_sock = passiveTCP(psv->sv_name, QLEN); else psv->sv_sock = passiveUDP(psv->sv_name); fd2sv[psv->sv_sock] = psv; nfds = MAX(psv->sv_sock+1, nfds); FD_SET(psv->sv_sock, &afds); } (void) signal(SIGCHLD, reaper); while (1) { memcpy(&rfds, &afds, sizeof(rfds)); if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) { if (errno == EINTR) continue; errexit("select error: %s\n", strerror(errno)); } for (fd=0; fd<nfds; ++fd) if (FD_ISSET(fd, &rfds)) { psv = fd2sv[fd]; if (psv->sv_useTCP) doTCP(psv); else psv->sv_func(psv->sv_sock); } } }
/*------------------------------------------------------------------------ * main - Concurrent TCP server for ECHO service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { pthread_t th; pthread_attr_t ta; char *service = "echo"; /* service name or port number */ struct sockaddr_in fsin; /* the address of a client */ unsigned int alen; /* length of client's address */ int msock; /* master server socket */ int ssock; /* slave server socket */ switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPechod [port]\n"); } msock = passiveTCP(service, QLEN); (void) pthread_attr_init(&ta); (void) pthread_attr_setdetachstate(&ta, PTHREAD_CREATE_DETACHED); (void) pthread_mutex_init(&stats.st_mutex, 0); if (pthread_create(&th, &ta, (void * (*)(void *))prstats, 0) < 0) errexit("pthread_create(prstats): %s\n", strerror(errno)); while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) { if (errno == EINTR) continue; errexit("accept: %s\n", strerror(errno)); } if (pthread_create(&th, &ta, (void * (*)(void *))TCPechod, (void *)(long)ssock) < 0) errexit("pthread_create: %s\n", strerror(errno)); } }
int main(int argc, char *argv[]) { pthread_t th; pthread_attr_t ta; struct sockaddr_in fsin; /* the from address of a client */ char *service = get_port(); /* service name or port number */ int msock, ssock; /* master & slave sockets */ int alen; /* from-address length */ int childpid; signal(SIGPIPE,SIG_IGN); signal(SIGCHLD,reaper); switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("<klaxon>\n"); } msock = passiveTCP(service, QLEN); printf("Server listening on: %s\n",get_port()); alen = sizeof(fsin); (void) pthread_attr_init(&ta); (void) pthread_attr_setdetachstate(&ta, PTHREAD_CREATE_DETACHED); while ( ((ssock = accept(msock, (struct sockaddr *)&fsin, &alen)) >= 0) && (pthread_create(&th,&ta,(void * (*) (void *))serv,(void *) ssock) == 0 ) ); printf("alen: %i\tssock: %i\tchildpid: %i\n",alen,ssock,childpid); /* if(childpid == 0) { close(msock); while(serv(ssock)); exit(0); } else errexit("<beep>"); */ }
/*------------------------------------------------------------------------ * main - Iterative TCP server for DAYTIME service *------------------------------------------------------------------------ */ int main(int argc, char *argv[]) { struct sockaddr_in fsin; /* the from address of a client */ char *service = "daytime"; /* service name or port number */ int msock, ssock; /* master & slave sockets */ unsigned int alen; /* from-address length */ pid_t pid; int status; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPdaytimed [port]\n"); } msock = passiveTCP(service, QLEN); while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) errexit("accept failed: %s\n", strerror(errno)); if((pid = fork()) == 0) /*create child process and run if successful*/ { close(msock); /*In slave prcess close master socket*/ printf("\nI am in child process, pid is:%d and parent id is:%d\n", getpid(), getppid()); TCPdaytimed(ssock); /*call tcpdaytimed function*/ (void) close(ssock); /*after function call close slave socket*/ exit(0); } } }
int main(int argc, char *argv[]) { int sockfd, new_sockfd; const char *port = "9001"; sockfd = passiveTCP(port,QLEN); if (sockfd < 0) error("ERROR opening socket"); while(1) { if(new_sockfd = accept(sockfd, 0, 0)) { pthread_t t; pthread_create(&t, 0, do_proxy, (void*)new_sockfd); } } close(new_sockfd); close(sockfd); return 0; }
int main(int argc, char*argv[]) { char *service = "daytime"; char buf[LINELEN + 1]; struct sockaddr_in fsin; unsigned int alen; int tsock; int usock; int nfds; fd_set rfds; tsock = passiveTCP("tcp", QLEN); usock = passiveUDP("udp"); nfds = MAX(tsock, usock) + 1; FD_ZERO(&rfds); while (1) { FD_SET(tsock, &rfds); (usock, &rfds); if (select(nfds, &rfds, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0) < 0) errexit("select error : %s\n", strerror(errno)); if (FD_ISSET(tsock, &rfds)) { int ssock; pthread_t thread_id; alen = sizeof(fsin); ssock = accept(tsock, (struct sockaddr *) &fsin, &alen); if (ssock < 0) errexit("accept failed: %s\n", strerror(errno)); if (pthread_create(&thread_id, NULL, connection_handler, (void*) &ssock) < 0) { perror("could not create thread"); return 1; } daytime(buf); (void) write(ssock, buf, strlen(buf)); (void) close(ssock); } if (FD_ISSET(usock, &rfds)) { alen = sizeof(fsin); pthread_t thread_id; if (recvfrom(usock, buf, sizeof(buf), 0, (struct sockaddr *) &fsin, &alen) < 0) errexit("recvfrom: %s\n", strerror(errno)); if (pthread_create(&thread_id, NULL, connection_handlerudp, (void*) &usock) < 0) { perror("could not create thread"); return 1; } daytime(buf); (void) sendto(usock, buf, strlen(buf), 0, (struct sockaddr*) &fsin, sizeof(fsin)); } } void *connection_handlerudp(void *socket_desc) { char buf[LINELEN + 1]; unsigned int alen; struct sockaddr_in fsin; int readsize; int sock = *(int*) socket_desc; alen = sizeof(fsin); while ((readsize = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &fsin, &alen)) > 0) { sendto(sock, buf, sizeof(buf), 0, (struct sockaddr *) &fsin, sizeof(fsin)); } if (readsize == 0) { puts("Client disconnected"); fflush(stdout); } else if (readsize == -1) { perror("recv failed"); } errexit("recvfrom: %s\n", strerror(errno)); }
// multiple-protocol super server int main(int argc, char **argv) { Service *psv, *fd2sv[NOFILE]; int fd, nfds; fd_set afds, rfds; // set port base portbase = 0; // check the arguments switch (argc) { case 1: break; case 2: portbase = atoi(argv[1]); break; default: ERROR("usage: superd [portbase]", EINVAL); return(1); } // signal handlers for exiting setCleanUp(); // check of any port base offset if (portbase == 0) checkPortBase(); // initialize array of services nfds = 0; FD_ZERO(&afds); for (psv = services; psv->service != NULL; psv++) { // allocate a socket switch (psv->protocol) { case UseUDP: psv->socket = passiveUDP(psv->service); if (psv->socket < 0) { ERRORD("passiveUDP failed", psv->socket, errno); return(2); } break; case UseTCP: psv->socket = passiveTCP(psv->service, QueueLength); if (psv->socket < 0) { ERRORD("passiveTCP failed", psv->socket, errno); return(2); } break; default: ERROR("invalid protocol in service table", EINVAL); return(2); } // map descriptor to service fd2sv[psv->socket] = psv; nfds = mymax(psv->socket+1, nfds); FD_SET(psv->socket, &afds); } // wait for a message and process it. while (1) { // copy active descriptors memcpy(&rfds, &afds, sizeof(rfds)); // wait for a calling if (select(nfds, &rfds, 0, 0, 0) < 0) { if (errno == EINTR) continue; ERROR("select error", errno); return(2); } // process active descriptors for (fd = 0; fd < nfds; fd++) { // check if active if ( ! FD_ISSET(fd, &rfds)) continue; // active, process according to protocol psv = fd2sv[fd]; switch (psv->protocol) { case UseTCP: doTCP(psv); break; case UseUDP: psv->server(psv->socket); break; default: ERRORD("invalid protocol", psv->protocol, EINVAL); return(2); } } } }
int main() { struct sockaddr_in cli_addr; int msock, ssock, rsock; /* ssock is sock between browser and socks server, rosk is sock between server and socks server*/ int alen; int childpid; gSocksConfig = NULL; /*global var recording for config content*/ msock = passiveTCP(SERVER_PORT, 5); // create socket waiting for client's link fprintf(stdout, "Server is listening on 140.113.215.186 %d\n", SERVER_PORT); //************************************ // read firewall rule from socks.conf //************************************ if(readSocksConfig() == FAILURE) { fprintf(stdout, "File: socks.conf parse error\n"); return 0; } else { //************************************ // use linking list to print out socks.conf content //************************************ socksConfig *printTest; printTest = gSocksConfig; /* point to global socksConfig */ while(printTest) { fprintf(stdout, "rule: %s, linking: %d, s_IP: %s, s_Port: %d, d_IP: %s, d_Port: %d\n", \ (printTest->ruleState == PERMIT) ? "PERMIT" : "DENY", printTest->linkingType, \ printTest->srcIP, printTest->srcPort, printTest->dstIP, printTest->dstPort); printTest = printTest->next; } } while(1) { alen = sizeof(cli_addr); ssock = accept(msock, (struct sockaddr *)&cli_addr, &alen); if(ssock < 0) { fprintf(stderr, "accept error: %s\n", strerror(errno)); continue; } if((childpid = fork()) < 0) { fprintf(stderr , "fork error\n"); close(ssock); } else if(childpid == 0) // create new process to handle new socks connection { close(msock); int readLen, writeLen = 0, writeOutLen = 0, rsock = -1;/* writeOutLen is for non-blocking write*/ socks4Packet *pMsgPacket = NULL, *pRepPacket = NULL; /* pMsgPacket is used to receive data packet from client, pRepPacket is for replying*/ struct sockaddr_in passSin; int passLen = sizeof(passSin); pMsgPacket = allocScoks4Packet(); if((readLen = recvMsg(ssock, pMsgPacket->dataBuf, DATABUFLEN)) < 0) // receive request and save in buf { fprintf(stderr, "Recv msg error: %s\n", strerror(errno)); socksBreak(pMsgPacket, pRepPacket, ssock, rsock); exit(0); } if(parseMsgPacket(pMsgPacket) != SUCCESS) // parse receive packet { fprintf(stderr, "Parse msg error\n"); socksBreak(pMsgPacket, pRepPacket, ssock, rsock); exit(0); } //************************************ // after parsing socks packet, save related info in pMsgPacket, then check with socks.conf rule // // rsock == -1 or psock == 1, my program will reply invalid packet(CD == 91) to client //************************************ if(checkPacketWithConfig(pMsgPacket, inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port)) == false) { pMsgPacket->rsock = -1; pMsgPacket->psock = -1; } else { //************************************ // if CONNECT mode, help client to connect remote server // // else if BIND mode, listen on a local mode, and wait for remote server to connect //************************************ if(pMsgPacket->CD == CONNECT) pMsgPacket->rsock = dstConnect(pMsgPacket); else if(pMsgPacket->CD == BIND) { if((pMsgPacket->psock = passiveTCP(0, 5)) > -1) { bzero((char *)&passSin, sizeof(passSin)); getsockname(pMsgPacket->psock, (struct sockaddr *)&passSin, &passLen); // use getsockname to get the bind port (assigned by system) pMsgPacket->dstPort = ntohs(passSin.sin_port); } } } pRepPacket = allocScoks4Packet(); //************************************ // create reply packet via parsing result // // and print out packet content and parsing result //************************************ if(creatRepPacket(pMsgPacket, pRepPacket) != SUCCESS) { fprintf(stderr, "Packet create error\n"); socksBreak(pMsgPacket, pRepPacket, ssock, \ pMsgPacket->CD == CONNECT ? pMsgPacket->rsock : pMsgPacket->psock); exit(0); } else { fprintf(stdout, "<S_IP>: %s, <S_PORT>: %d, <VN>: %u, <CD>: %u, <D_IP>: %s, <D_PORT>: %d, <CMD>: %s, <REPLY>: %s\n",\ inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port), pMsgPacket->VN, \ (pMsgPacket->CD == CONNECT) ? 1 : 2, \ (pMsgPacket->domainName == NULL)? pMsgPacket->dstIP : pMsgPacket->domainName, \ pMsgPacket->dstPort, (pMsgPacket->CD == CONNECT) ? "CONNECT" : "BIND", \ (pRepPacket->CD == 90) ? "ACCEPT" : "REJECT"); } //************************************ // send reply packet to client //************************************ while(writeOutLen < SOCKSREPLAYLEN) { writeLen = sendMsg(ssock, pRepPacket->dataBuf + writeOutLen, SOCKSREPLAYLEN - writeOutLen); writeOutLen += writeLen; } // invalid request packet if((pMsgPacket->CD == CONNECT && pMsgPacket->rsock == -1) ||\ (pMsgPacket->CD == BIND && pMsgPacket->psock == -1)) { if(pMsgPacket->CD == CONNECT) fprintf(stderr, "CONNECT: Invalid remote host\n"); else if(pMsgPacket->CD == BIND) fprintf(stderr, "BIND: Invalid socks server port/socket\n"); socksBreak(pMsgPacket, pRepPacket, ssock, \ pMsgPacket->CD == CONNECT ? pMsgPacket->rsock : pMsgPacket->psock); exit(0); } //************************************ // if BIND mode, wait for server to connect, then reply success msg to client //************************************ if(pMsgPacket->CD == BIND) { unsigned char secReplyPacket[DATABUFLEN]; memset(secReplyPacket, 0, DATABUFLEN); bzero((char *)&passSin, sizeof(passSin)); writeOutLen = 0; pMsgPacket->rsock = accept(pMsgPacket->psock, (struct sockaddr *)&passSin, &passLen); //************************************ // msg format: 0 (0x5A or 0x5B) ignore ignore //************************************ secReplyPacket[0] = 0; secReplyPacket[1] = (pMsgPacket->rsock < 0) ? 91 : 90; while(writeOutLen < SOCKSREPLAYLEN) { writeLen = sendMsg(ssock, secReplyPacket + writeOutLen, \ SOCKSREPLAYLEN - writeOutLen); writeOutLen += writeLen; } // fail, exit anyway if(pMsgPacket->rsock < 0) { fprintf(stderr, "BIND: accept error: %s\n", strerror(errno)); close(pMsgPacket->rsock); socksBreak(pMsgPacket, pRepPacket, ssock, \ pMsgPacket->CD == CONNECT ? pMsgPacket->rsock : pMsgPacket->psock); exit(0); } } //************************************ // help client and server do packet exchange //************************************ relayData(ssock, pMsgPacket->rsock); socksBreak(pMsgPacket, pRepPacket, ssock, \ pMsgPacket->CD == CONNECT ? pMsgPacket->rsock : pMsgPacket->psock); freeSocksConfig(); fprintf(stdout, "One client is leaving and its IP and port are %s and %d\n",\ inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port)); exit(0); } else // close sock with client close(ssock); } close(msock); freeSocksConfig(); return 0; }