Example #1
0
int main()
{
	int server_sockfd, client_sockfd;
	int server_len, client_len;
	struct sockaddr_in server_address;
	struct sockaddr_in client_address;
	int result;
	fd_set readfds, testfds;

	server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr = INADDR_ANY;
	server_address.sin_port = htons(9734);
	server_len = sizeof(server_address);

	bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
	listen(server_sockfd, 5);

	FD_ZERO(&readfds);
	FD_SET(server_sockfd, &readfds);

	while (1) {
		char ch;
		int fd;
		int nread;

		testfds = readfds;

		printf("server waiting\n");
		result = select(FD_SETSIZE, &testfds, (fd_set *)0,
				        (fd_set *)0, (struct timeval *)0);

		if (result < 1) {
			perror("server5");
			exit(1);
		}

		for (fd = 0; fd < FD_SETSIZE; fd++) {
			if (FD_ISSET(fd, &testfds)) {
				if (fd == server_sockfd) {
					client_len = sizeof(client_address);
					client_sockfd = accept(server_sockfd,
							(struct sockaddr *)&client_address, &client_len);
					FD_SET(client_sockfd, &readfds);
					printf("add client on fd %d\n", client_sockfd);
				} else {
					ioctl(fd, FIONREAD, &nread);

					if (nread == 0) {
						close(fd);
						FD_CLR(fd, &readfds);
						printf("removing client on fd %d\n", fd);
					} else {
						read(fd, &ch, 1);
						sleep(5);
						printf("serving client on fd %d\n", fd);
						ch++;
						write(fd, &ch, 1);
					}
				}
			}
		}
	}
}
Example #2
0
extract::process::output const
extract::process::call(
	argument_list const &_args)
{
	FCPPT_ASSERT(
		!_args.empty());

	std::size_t const
		reading_end = 
			static_cast<std::size_t>(
				0),
		writing_end = 
			static_cast<std::size_t>(
				1);

	int out_pipe[2];
	int err_pipe[2];

	if (pipe(out_pipe) == -1 || pipe(err_pipe) == -1)
		throw 
			fcppt::exception(
				FCPPT_TEXT("one of the pipes failed"));
	
	pid_t const pid = 
		fork();

	if (pid == 0)
	{
		close(
			out_pipe[reading_end]);
		close(
			err_pipe[reading_end]);
		dup2(
			out_pipe[writing_end],
			STDOUT_FILENO);
		dup2(
			err_pipe[writing_end],
			STDERR_FILENO);
		close(
			out_pipe[writing_end]);
		close(
			err_pipe[writing_end]);
		
		exec(
			_args);
	}

	close(
		out_pipe[writing_end]);
	close(
		err_pipe[writing_end]);

	fd_set master_fds;
	FD_ZERO(
		&master_fds);
	
	FD_SET(
		out_pipe[reading_end],
		&master_fds);

	FD_SET(
		err_pipe[reading_end],
		&master_fds);

	output out;
	int eof_count = 
		0;
	while (eof_count < 2)
	{
		fd_set read_fds = master_fds;

		int 
			maxfd = 
				std::max(
					out_pipe[reading_end],
					err_pipe[reading_end]),
			select_return = 
				select(
					maxfd+1,
					&read_fds,
					0,
					0,
					0);

		if (select_return == -1)
			throw 
				fcppt::exception(
					FCPPT_TEXT("select failed"));

		int const fds[2] = 
			{ 
				out_pipe[reading_end],
				err_pipe[reading_end] 
			};

		fcppt::string *outs[2] = 
			{
				&out.out,
				&out.err
			};
		for (int i = 0; i < 2; ++i)
		{
			if (!FD_ISSET(fds[i],&read_fds))
				continue;

			ssize_t const buffer_size = 
				static_cast<ssize_t>(
					1024);

			char char_buffer[buffer_size];

			ssize_t const b = ::read(
				fds[i],
				char_buffer,
				static_cast<std::size_t>(
					buffer_size-1));
			
			if (b == static_cast<ssize_t>(0))
			{
	//			fcppt::io::cerr << "recieved eof on fd " << fds[i] << "\n";
				eof_count++;
				FD_CLR(
					fds[i],
					&master_fds);
				continue;
			}
			
			if (b == static_cast<ssize_t>(-1))
				throw 
					fcppt::exception(
						FCPPT_TEXT("read failed"));

	//		fcppt::io::cerr << "received the following crap: " << fcppt::string(char_buffer,char_buffer+b) << "\n";

			outs[i]->insert(
				outs[i]->end(),
				char_buffer,
				char_buffer + b);
		}
	}
	
	waitpid(
		pid,
		(&out.exit_code),
		0);
	
	return out;
}
Example #3
0
void relay_tcp(SOCKS_STATE *state)
{
  fd_set   rfds, xfds;
  int      nfds, sfd;
  struct   timeval tv;
  struct   timezone tz;
  ssize_t  wc;
  rlyinfo  ri;
  int      done;
  u_long   max_count = idle_timeout;
  u_long   timeout_count;
  LOGINFO	li;

  memset(&ri, 0, sizeof(ri));
  memset(&li, 0, sizeof(li));
  ri.ss = (struct sockaddr *)NULL;
  ri.len = 0;
  ri.nr = BUFSIZE;

  nfds = MAX(state->r, state->s);
  setsignal(SIGALRM, timeout);
  gettimeofday(&li.start, &tz);
  li.bc = li.upl = li.dnl = 0;
  ri.flags = 0; timeout_count = 0;
  for (;;) {
    FD_ZERO(&rfds);
    FD_SET(state->s, &rfds); FD_SET(state->r, &rfds);
    if (ri.flags == 0) {
      FD_ZERO(&xfds);
      FD_SET(state->s, &xfds); FD_SET(state->r, &xfds);
    }
    done = 0;
    /* idle timeout related setting. */
    tv.tv_sec = 60; tv.tv_usec = 0;   /* unit = 1 minute. */
    tz.tz_minuteswest = 0; tz.tz_dsttime = 0;
    sfd = select(nfds+1, &rfds, 0, &xfds, &tv);
    if (sfd > 0) {
      if (FD_ISSET(state->r, &rfds)) {
	ri.from = state->r; ri.to = state->s; ri.flags = 0;
	if ((wc = forward(&ri)) <= 0)
	  done++;
	else
	  li.bc += wc; li.dnl += wc;

	FD_CLR(state->r, &rfds);
      }
      if (FD_ISSET(state->r, &xfds)) {
	ri.from = state->r; ri.to = state->s; ri.flags = MSG_OOB;
	if ((wc = forward(&ri)) <= 0)
	  done++;
	else
	  li.bc += wc; li.dnl += wc;
	FD_CLR(state->r, &xfds);
      }
      if (FD_ISSET(state->s, &rfds)) {
	ri.from = state->s; ri.to = state->r; ri.flags = 0;
	if ((wc = forward(&ri)) <= 0)
	  done++;
	else
	  li.bc += wc; li.upl += wc;
	FD_CLR(state->s, &rfds);
      }
      if (FD_ISSET(state->s, &xfds)) {
	ri.from = state->s; ri.to = state->r; ri.flags = MSG_OOB;
	if ((wc = forward(&ri)) <= 0)
	  done++;
	else
	  li.bc += wc; li.upl += wc;
	FD_CLR(state->s, &xfds);
      }
      if (done > 0)
	break;
    } else if (sfd < 0) {
      if (errno != EINTR)
	break;
    } else { /* sfd == 0 */
      if (max_count != 0) {
	timeout_count++;
	if (timeout_count > max_count)
	  break;
      }
    }
  }
  gettimeofday(&li.end, &tz);
  log_transfer(state->si, &li);

  close(state->r);
  close(state->s);
}
Example #4
0
/**
 * new connecion comes, copy file descroptor of new connecton to child
 * process , parent process select
 * @return  0
 */
int main(int argc, char **argv)
{

    int res;
    res = register_sig_handler();
    if (res < 0)
        err_sys("register_sig_handler is err");

    my_getopt(argc, argv);

    int pipefd[2];

    int socket_fd;
    res = srv_socket_init(&socket_fd, 50, PORT);
    if (res < 0)
        err_sys("srv_socket_init err");

    fd_set myset;
    FD_ZERO(&myset);
    FD_SET(socket_fd, &myset);
    int max = socket_fd;

    arraychild = (child_t *) malloc(sizeof(child_t) * childnum);
    memset(arraychild, 0, sizeof(child_t) * childnum);
    for (int i = 0 ; i < childnum; i++)
    {

        res = socketpair(AF_LOCAL, SOCK_STREAM, 0, pipefd);
        if (res < 0)
            err_sys("socketpair is err");
        arraychild[i].child_pipefd = pipefd[0];
        FD_SET(pipefd[0], &myset);
        if (pipefd[0] > max)
            max = pipefd[0];

        int pid = fork();
        if (pid < 0)
            err_sys("fork err");

        if (pid == 0)
        {
            srv_socket_destory(&socket_fd);

            int connfd;
            int childpid = getpid();
            while(1)
            {

                char c;
                res = read_fd(pipefd[1], &c, 1, &connfd);
                if (res < 0)
                    err_sys("read_fd err");
                fprintf(stdout, "pid is %d, accept success.\n",childpid);
                child_process(connfd);

                write(pipefd[1], "", 1);

                srv_socket_close(&connfd);
            }
            //exit(0);
        }
        else
        {
            arraychild[i].child_pid = pid;
        }
    }

    struct sigaction myact;
    myact.sa_handler = sig_int_handler;
    if (sigaction(SIGINT, &myact, NULL) < 0)
        err_sys("sigaction err");

    int navail = childnum;
    fd_set rset ;
    int newfd;
    int i = 0;
    while(1)
    {
        rset = myset;
        if (navail <=0 )
            FD_CLR(socket_fd, &rset);


        select(max + 1, &rset, NULL, NULL, NULL);
        if (FD_ISSET(socket_fd, &rset))
        {
            newfd = accept(socket_fd, NULL, NULL);

            for (i = 0; i < childnum; i++)
            {
                if (arraychild[i].child_status == 0)
                    break;
            }

            res = write_fd(arraychild[i].child_pipefd, "", 1, newfd);
            if (res < 0)
            {
                continue;
            }
            srv_socket_close(&newfd);
            arraychild[i].child_status = 1;
            arraychild[i].child_count++;
            navail--;
        }
        for (int i = 0; i < childnum; i++)
        {
            char c;
            if (FD_ISSET(arraychild[i].child_pipefd, &rset))
            {
                read(arraychild[i].child_pipefd, &c, 1);
                arraychild[i].child_status = 0;
                navail++;
            }
        }
    }

    return 0;
}
Example #5
0
int main() {
	
    int fd, novofd,nbytes,j,fdmax;
    struct sockaddr_in addr, client_addr;
    int client_addr_size;
    char buffer[BUF_SIZE];
    int clientes_fd[MAX];// array com o fds dos clientes
    fd_set master;  // descritor de arquivo mestre
    fd_set ler_fds;    //  descritor de arquivo para temporario
	FD_ZERO(&master);   //limpa os conjuntos mestre e temporário
    FD_ZERO(&ler_fds);
    int yes=1;
  
	
	bzero((void *) &addr, sizeof(addr));
    addr.sin_family      = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port        = htons(SERVER_PORT);
    
	
    if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
	erro("na funcao socket");
	
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (int)) == -1) {

            perror ("setsockopt");
            exit (1);
        }
	
    if ( bind(fd,(struct sockaddr*)&addr,sizeof(addr)) < 0)
	erro("na funcao bind");
    if( listen(fd, 100) < 0)
		erro("na funcao listen");
		//adiciona o socket em escura ao conjunto master
		FD_SET(fd, &master);

	clientes_fd[0]=fd;
	fdmax=fd;


	while(1){
			
            ler_fds = master; // copia os master para o temporario
            
            if (select (fdmax+1,  &ler_fds, NULL, NULL, NULL)== -1) {
                
                perror ("select");
                exit(1);
            }

            int i;// percorre as conexões existentes em busca de dados
            for ( i = 0; i <=fdmax; i++) {
        
                if  ( FD_ISSET ( i,  &ler_fds))  { 
                    
                    if ( i == clientes_fd[0]) {
                     
                        //trata novas conexões
                       client_addr_size = sizeof(client_addr);
                        
                        if (( novofd = accept(fd,(struct sockaddr *)&client_addr, &client_addr_size)) == -1)  {
                            perror ("accept");
                        } else {
                            FD_SET ( novofd , &master);//adiciona ao mestre
                            char print[150]="->";
							char t[5];
							
							strcat(print,"servidor : nova conexão de ");
							strcat(print, inet_ntoa(client_addr.sin_addr));
							strcat(print," no  socket ");
							sprintf(t, "%d", novofd);
							strcat(print, t);
							strcat(print, "\n");
							
							for (j = 0; j<MAX; j++)  {
                                
                                //envia a todos os clientes
                                if (FD_ISSET (j, &master)) {
                                    // exceto a nós e ao socket em escuta
                                  
                                    if (j != fd &&j != novofd) {
                                         if (write(j,print,strlen(print)) == -1) {
                                        perror ("write");
                                       
                            }}}}
                            print[0]='\0';
                            
                            if(fdmax<novofd){
								fdmax=novofd;
								novofd=0;
							}
							clientes_fd[coloca_array(clientes_fd)]=novofd;
							
                        
                    }} else {

                        // cuida dos dados do cliente
                      
                           if  ( (nbytes=(read (i, buffer, BUF_SIZE-1)))>= 0) {
                            
                            // recebeu erro ou a conexão foifechada pelo cliente
                            if (nbytes == 0) {
								char printR[150]="->";
								char p[5];
								strcat(printR," servidor : o Cliente foi desligado ");
								strcat(printR, inet_ntoa(client_addr.sin_addr));
								strcat(printR," no  socket ");
								sprintf(p, "%d", i);
								strcat(printR, p);
								strcat(printR, "\n");
							
								for (j = 0; j<MAX; j++)  {
                                
                                //envia a todos os clientes
									if (FD_ISSET (j, &master)) {
                                    // menos aos nós e ao socket em escuta
                                  
										if (j != fd &&j != novofd) {
											if (write(j,printR,strlen(printR)) == -1) {
											perror ("write");
                                       
                            }}}}
                            printR[0]='\0';
                                FD_CLR( i , &master); // clear do conjunto mestre
                                search(clientes_fd, i);
                            } else if(nbytes==-1) {
                                perror ("read"); 
                            }
                           
                        }
                            // temos alguns dados do cliente
                            for (j = 0; j<MAX; j++)  {
                                
                                //envia a todos os clientes
                                if (FD_ISSET (j, &master)) {
                                    // exceto a nós e ao socket em escuta
                                  
                                    if (j != fd &&j!=i ) {
                                         if (write(j,buffer,nbytes) == -1) {
                                        perror ("write");
                                         }
                                    }
                                }
                            }
                        }
                    } 
                }
            }
       
    
  
  return 0;
}
/* handle irc server connectipn */
void irc_perform(int changesec)
{
  channel_t *ch;
  unsigned int ss;
  unsigned int i;
  unsigned int j;
  int length;
  int timeout;

  updatecontext();

  for (ss=0; ss<gdata.networks_online; ++ss) {
    gnetwork = &(gdata.networks[ss]);

    if (gdata.needsswitch) {
      switchserver(-1);
      continue;
    }

    /*----- see if gdata.ircserver is sending anything to us ----- */
    if (gnetwork->serverstatus == SERVERSTATUS_CONNECTED) {
      if (FD_ISSET(gnetwork->ircserver, &gdata.readset)) {
        char tempbuffa[INPUT_BUFFER_LENGTH];
        gnetwork->lastservercontact = gdata.curtime;
        gnetwork->servertime = 0;
        memset(&tempbuffa, 0, INPUT_BUFFER_LENGTH);
        length = readserver_ssl(&tempbuffa, INPUT_BUFFER_LENGTH);

        if (length < 1) {
          if (errno != EAGAIN) {
            ioutput(OUT_S|OUT_L|OUT_D, COLOR_RED,
                    "Closing Server Connection on %s: %s",
                    gnetwork->name, (length<0) ? strerror(errno) : "Closed");
            if (gdata.exiting) {
              gnetwork->recentsent = 0;
            }
            close_server();
            mydelete(gnetwork->curserveractualname);
          }
          continue;
        }

        j = strlen(gnetwork->server_input_line);
        for (i=0; i<(unsigned int)length; ++i) {
          if ((tempbuffa[i] == '\n') || (j == (INPUT_BUFFER_LENGTH-1))) {
            if (j && (gnetwork->server_input_line[j-1] == 0x0D)) {
              --j;
            }
            gnetwork->server_input_line[j] = '\0';
            ir_parseline(gnetwork->server_input_line);
            j = 0;
          } else {
            gnetwork->server_input_line[j] = tempbuffa[i];
            ++j;
          }
        }
        gnetwork->server_input_line[j] = '\0';
      }
      continue;
    }

    if (gnetwork->serverstatus == SERVERSTATUS_SSL_HANDSHAKE) {
      if ((FD_ISSET(gnetwork->ircserver, &gdata.writeset)) || (FD_ISSET(gnetwork->ircserver, &gdata.readset))) {
        handshake_ssl();
      }
      if (changesec)
        irc_server_timeout();
      continue;
    }

    if (gnetwork->serverstatus == SERVERSTATUS_TRYING) {
      if (FD_ISSET(gnetwork->ircserver, &gdata.writeset)) {
        int callval_i;
        int connect_error;
        SIGNEDSOCK int connect_error_len = sizeof(connect_error);
        SIGNEDSOCK int addrlen;

        callval_i = getsockopt(gnetwork->ircserver,
                               SOL_SOCKET, SO_ERROR,
                               &connect_error, &connect_error_len);

        if (callval_i < 0) {
          outerror(OUTERROR_TYPE_WARN,
                   "Couldn't determine connection status: %s on %s",
                   strerror(errno), gnetwork->name);
          close_server();
          continue;
        }
        if (connect_error) {
          ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR,
                  "Server Connection Failed: %s on %s", strerror(connect_error), gnetwork->name);
          close_server();
          continue;
        }

        ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR,
                "Server Connection to %s Established, Logging In",  gnetwork->name);
        gnetwork->serverstatus = SERVERSTATUS_CONNECTED;
        gnetwork->connecttime = gdata.curtime;
        gnetwork->botstatus = BOTSTATUS_LOGIN;
        ch = irlist_get_head(&(gnetwork->channels));
        if (ch == NULL) {
          gnetwork->botstatus = BOTSTATUS_JOINED;
          start_sends();
        }
        FD_CLR(gnetwork->ircserver, &gdata.writeset);

        addrlen = sizeof(gnetwork->myip);
        bzero((char *) &(gnetwork->myip), sizeof(gnetwork->myip));
        if (getsockname(gnetwork->ircserver, &(gnetwork->myip.sa), &addrlen) >= 0) {
          if (gdata.debug > 0) {
            char *msg;
            msg = mymalloc(maxtextlength);
            my_getnameinfo(msg, maxtextlength -1, &(gnetwork->myip.sa));
            ioutput(OUT_S, COLOR_YELLOW, "using %s", msg);
            mydelete(msg);
          }
          if (!gnetwork->usenatip) {
            gnetwork->ourip = ntohl(gnetwork->myip.sin.sin_addr.s_addr);
            if (gdata.debug > 0) {
              ioutput(OUT_S, COLOR_YELLOW, "ourip = " IPV4_PRINT_FMT,
                      IPV4_PRINT_DATA(gnetwork->ourip));
            }
          }
        } else {
          outerror(OUTERROR_TYPE_WARN, "couldn't get ourip on %s", gnetwork->name);
        }

        handshake_ssl();
      }
      if (changesec)
        irc_server_timeout();
      continue;
    }

    if (gnetwork->serverstatus == SERVERSTATUS_RESOLVING) {
      if (FD_ISSET(gnetwork->serv_resolv.sp_fd[0], &gdata.readset)) {
        res_addrinfo_t remote;
        length = read(gnetwork->serv_resolv.sp_fd[0],
                      &remote, sizeof(res_addrinfo_t));

        kill(gnetwork->serv_resolv.child_pid, SIGKILL);
        FD_CLR(gnetwork->serv_resolv.sp_fd[0], &gdata.readset);

        if (length != sizeof(res_addrinfo_t)) {
          ioutput(OUT_S|OUT_L|OUT_D, COLOR_RED,
                  "Error resolving server %s on %s",
                  gnetwork->curserver.hostname, gnetwork->name);
          gnetwork->serverstatus = SERVERSTATUS_NEED_TO_CONNECT;
        } else {
          /* continue with connect */
          if (connectirc2(&remote)) {
            /* failed */
            gnetwork->serverstatus = SERVERSTATUS_NEED_TO_CONNECT;
          }
        }
      }
      if (changesec) {
        timeout = irc_server_is_timeout();
        if (timeout > 0) {
          kill(gnetwork->serv_resolv.child_pid, SIGKILL);
          ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR,
                  "Server Resolve Timed Out (%u seconds) on %s", timeout, gnetwork->name);
          gnetwork->serverstatus = SERVERSTATUS_NEED_TO_CONNECT;
        }
      }
      continue;
    }

    if (gnetwork->offline)
      continue;

    if (gnetwork->serverstatus == SERVERSTATUS_NEED_TO_CONNECT) {
      if (changesec) {
        timeout = irc_server_is_timeout();
        if (timeout > 0) {
          if (gdata.debug > 0) {
            ioutput(OUT_S, COLOR_YELLOW,
                    "Reconnecting to server (%u seconds) on %s",
                    timeout, gnetwork->name);
          }
          switchserver(-1);
        }
      }
      continue;
    }

  } /* networks */
  gnetwork = NULL;

  /* reset after done on all networks */
  if (gdata.needsswitch)
    gdata.needsswitch = 0;
}
Example #7
0
int main(int argc,char *argv[]){
	int i,fd,nmaxconn,nfiles,maxfd,nconn,flags;
	char buf[MAXLINE];
	fd_set rs,ws;

	if(argc < 4)
		err_quit("usage : web <#conn> hostname homepage file1 ...");
	nmaxconn = atoi(argv[1]);

	nfiles = min(argc-4,MAXFILES);

	for(i=0;i<nfiles;i++){
		file[i].f_name = argv[4+i];
		file[i].f_host = argv[2];
		file[i].flags = 0;
	}
	home_page(argv[2],argv[3]);

	FD_ZERO(&rs);
	FD_ZERO(&ws);
	maxfd = -1;
	nconn = 0;
	nleftconn = nlefttoread = nfiles;

	while(nlefttoread > 0){
		while(nconn < nmaxconn && nleftconn > 0){
			for(i=0;i<nfiles;i++)
				if(file[i].flags != 0)
					break;
			if(i == nfiles)
				err_quit("nleftconn = %d but nothing found\n",nleftconn);
			start_connect(&file[i]);
			nconn++;
			nleftconn--;
		}
		rs = rset;
		ws = wset;
		Select(maxfd+1,&rset,&wset,NULL,NULL);
		
		for(i=0;i<nfiles;i++){
			flags = file[i].flags;
			if(flags == 0 || flags == F_DONE)
				continue;
			fd = file[i].f_fd;
			if(flags &  F_CONNECTING && (FD_ISSET(fd,&rset) || FD_ISSET(fd,&wset))){
				n=sizeof(error);
				if(getsockopt(fd,SOL_SOCKET,SO_ERROR,&error,&n) < 0 || error != 0)
					err_ret("nonblocking connect failed for %s\n",file[i].f_name);
				printf("connection established for %s\n",file[i].f_name);
				FD_CLR(fd,&wset);
				write_get_cmd(&file[i]);
			}else if(flags & F_READING && FD_ISSET(fd,&rset)){
				if((n = nread(fd,buf,sizeof(buf))) == 0){
					printf("end-of-file on %s\n",file[i].f_name);
					Close(fd);
					file[i].flags = F_DONE;
					FD_CLR(fd,&rset);
					nconn--;
					nlefconn--;
					nlefttoread--;
				}else {
					printf("read %d bytes from %s\n",n,file[i].f_name);
				}
			}
		}
	}
	exit(0);
}
Example #8
0
/*** Call Manager *************************************************************/
int callmgr_main(int argc, char **argv, char **envp)
{
    struct in_addr inetaddr;
    int inet_sock, unix_sock;
    fd_set call_set;
    PPTP_CONN * conn;
    VECTOR * call_list;
    int max_fd = 0;
    volatile int first = 1;
    int retval;
    int i;
    char * volatile phonenr;
    /* Step 0: Check arguments */
    if (argc < 2) 
        fatal("Usage: %s ip.add.ress.here [--phone <phone number>]", argv[0]);
    phonenr = argc == 3 ? argv[2] : NULL;
    if (inet_aton(argv[1], &inetaddr) == 0)
        fatal("Invalid IP address: %s", argv[1]);
    routing_init(inet_ntoa(inetaddr));
    routing_start();
    /* Step 1: Open sockets. */
    if ((inet_sock = open_inetsock(inetaddr)) < 0)
        fatal("Could not open control connection to %s", argv[1]);
    if ((unix_sock = open_unixsock(inetaddr)) < 0)
        fatal("Could not open unix socket for %s", argv[1]);
    /* Step 1b: FORK and return status to calling process. */
    switch (fork()) {
        case 0: /* child. stick around. */
            break;
        case -1: /* failure.  Fatal. */
            fatal("Could not fork.");
        default: /* Parent. Return status to caller. */
            exit(0);
    }
    /* re-open stderr as /dev/null to release it */
    file2fd("/dev/null", "wb", STDERR_FILENO);
    /* Step 1c: Clean up unix socket on TERM */
    if (sigsetjmp(callmgr_env, 1) != 0)
        goto cleanup;
    signal(SIGINT, callmgr_sighandler);
    signal(SIGTERM, callmgr_sighandler);
    signal(SIGPIPE, callmgr_do_nothing);
    signal(SIGUSR1, callmgr_do_nothing); /* signal state change
                                            wake up accept */
    /* Step 2: Open control connection and register callback */
    if ((conn = pptp_conn_open(inet_sock, 1, NULL/* callback */)) == NULL) {
        close(unix_sock); close(inet_sock); fatal("Could not open connection.");
    }
    FD_ZERO(&call_set);
    call_list = vector_create();
    { 
        struct local_conninfo *conninfo = malloc(sizeof(*conninfo));
        if (conninfo == NULL) {
            close(unix_sock); close(inet_sock); fatal("No memory.");
        }
        conninfo->call_list = call_list;
        conninfo->call_set  = &call_set;
        pptp_conn_closure_put(conn, conninfo);
    }
    if (sigsetjmp(callmgr_env, 1) != 0) goto shutdown;
    /* Step 3: Get FD_SETs */
    max_fd = unix_sock;
    do {
        int rc;
        fd_set read_set = call_set, write_set;
        FD_ZERO (&write_set);
        if (pptp_conn_established(conn)) {
	  FD_SET (unix_sock, &read_set);
	  if (unix_sock > max_fd) max_fd = unix_sock;
	}
        pptp_fd_set(conn, &read_set, &write_set, &max_fd);
        for (; max_fd > 0 ; max_fd--) {
            if (FD_ISSET (max_fd, &read_set) ||
                    FD_ISSET (max_fd, &write_set))
                break;
        }
        /* Step 4: Wait on INET or UNIX event */
        if ((rc = select(max_fd + 1, &read_set, &write_set, NULL, NULL)) <0) {
	  if (errno == EBADF) break;
	  /* a signal or somesuch. */
	  continue;
	}
        /* Step 5a: Handle INET events */
        rc = pptp_dispatch(conn, &read_set, &write_set);
	if (rc < 0)
	    break;
        /* Step 5b: Handle new connection to UNIX socket */
        if (FD_ISSET(unix_sock, &read_set)) {
            /* New call! */
            struct sockaddr_un from;
            socklen_t len = sizeof(from);
            PPTP_CALL * call;
            struct local_callinfo *lci;
            int s;
            /* Accept the socket */
            FD_CLR (unix_sock, &read_set);
            if ((s = accept(unix_sock, (struct sockaddr *) &from, &len)) < 0) {
                warn("Socket not accepted: %s", strerror(errno));
                goto skip_accept;
            }
            /* Allocate memory for local call information structure. */
            if ((lci = malloc(sizeof(*lci))) == NULL) {
                warn("Out of memory."); close(s); goto skip_accept;
            }
            lci->unix_sock = s;
            /* Give the initiator time to write the PIDs while we open
             * the call */
            call = pptp_call_open(conn, call_callback, phonenr);
            /* Read and store the associated pids */
            read(s, &lci->pid[0], sizeof(lci->pid[0]));
            read(s, &lci->pid[1], sizeof(lci->pid[1]));
            /* associate the local information with the call */
            pptp_call_closure_put(conn, call, (void *) lci);
            /* The rest is done on callback. */
            /* Keep alive; wait for close */
            retval = vector_insert(call_list, s, call); assert(retval);
            if (s > max_fd) max_fd = s;
            FD_SET(s, &call_set);
            first = 0;
        }
skip_accept: /* Step 5c: Handle socket close */
        for (i = 0; i < max_fd + 1; i++)
            if (FD_ISSET(i, &read_set)) {
                /* close it */
                PPTP_CALL * call;
                retval = vector_search(call_list, i, &call);
                if (retval) {
                    struct local_callinfo *lci =
                        pptp_call_closure_get(conn, call);
                    log("Closing connection (unhandled)");
                    if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM);
                    if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM);
                    free(lci);
                    /* soft shutdown.  Callback will do hard shutdown later */
                    pptp_call_close(conn, call);
                    vector_remove(call_list, i);
                }
                FD_CLR(i, &call_set);
                close(i);
            }
    } while (vector_size(call_list) > 0 || first);
shutdown:
    {
        int rc;
        fd_set read_set, write_set;
        struct timeval tv;
	signal(SIGINT, callmgr_do_nothing);
	signal(SIGTERM, callmgr_do_nothing);
        /* warn("Shutdown"); */
        /* kill all open calls */
        for (i = 0; i < vector_size(call_list); i++) {
            PPTP_CALL *call = vector_get_Nth(call_list, i);
            struct local_callinfo *lci = pptp_call_closure_get(conn, call);
            log("Closing connection (shutdown)");
            pptp_call_close(conn, call);
            if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM);
            if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM);
        }
        /* attempt to dispatch these messages */
        FD_ZERO(&read_set);
        FD_ZERO(&write_set);
        pptp_fd_set(conn, &read_set, &write_set, &max_fd);
	tv.tv_sec = 0;
	tv.tv_usec = 0;
	select(max_fd + 1, &read_set, &write_set, NULL, &tv);
        rc = pptp_dispatch(conn, &read_set, &write_set);
	if (rc > 0) {
	  /* wait for a respond, a timeout because there might not be one */ 
	  FD_ZERO(&read_set);
	  FD_ZERO(&write_set);
	  pptp_fd_set(conn, &read_set, &write_set, &max_fd);
	  tv.tv_sec = 2;
	  tv.tv_usec = 0;
	  select(max_fd + 1, &read_set, &write_set, NULL, &tv);
	  rc = pptp_dispatch(conn, &read_set, &write_set);
	  if (rc > 0) {
	    if (i > 0) sleep(2);
	    /* no more open calls.  Close the connection. */
	    pptp_conn_close(conn, PPTP_STOP_LOCAL_SHUTDOWN);
	    /* wait for a respond, a timeout because there might not be one */ 
	    FD_ZERO(&read_set);
	    FD_ZERO(&write_set);
	    pptp_fd_set(conn, &read_set, &write_set, &max_fd);
	    tv.tv_sec = 2;
	    tv.tv_usec = 0;
	    select(max_fd + 1, &read_set, &write_set, NULL, &tv);
	    pptp_dispatch(conn, &read_set, &write_set);
	    if (rc > 0) sleep(2);
	  }
	}
        /* with extreme prejudice */
        pptp_conn_destroy(conn);
        vector_destroy(call_list);
    }
cleanup:
    signal(SIGINT, callmgr_do_nothing);
    signal(SIGTERM, callmgr_do_nothing);
    close_inetsock(inet_sock, inetaddr);
    close_unixsock(unix_sock, inetaddr);
    return 0;
}
Example #9
0
int main(int argc, char* argv[])
{

    int i , maxi , maxfd , listenfd , connfd , sockfd ;
    int nready , client[ FD_SETSIZE ] ;
    ssize_t n ;
    fd_set rset , allset ;
    char buf [ MAXLINE ];
    socklen_t clilen ;
    struct sockaddr_in cliaddr , servaddr ;

		//creat socket
    listenfd = socket( AF_INET , SOCK_STREAM , 0 );
		//set socket
    bzero(&servaddr , sizeof( servaddr ));
    servaddr.sin_family = AF_INET ;
    servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
    servaddr.sin_port = htons( SERV_PORT ) ;
		//bind port
    bind(listenfd , (SA*) &servaddr ,sizeof(servaddr) );
		//listen port listenfd
    listen(listenfd , 10 );  // max client is 10
		//consider maxfd 
    maxfd = listenfd ;
    //initial maxi which is num of fd
		maxi = -1;
		//all client port is closed now
    for(i = 0; i < FD_SETSIZE ; i++) client[i] = -1 ;
    
		//initial select set
		FD_ZERO(&allset);
		//wait listenfd which is in allset when select
    FD_SET(listenfd , &allset );

    printf("ready to wait \n listenfd=%d",listenfd);

    for(;;)
    {
        rset = allset ;
				//nready is the fd ready to ready
        nready = select( maxfd + 1 , &rset , NULL , NULL , NULL );

        if(FD_ISSET(listenfd , &rset) ){
						//connect to ready client
            clilen = sizeof( cliaddr ) ;
            connfd = accept( listenfd , (SA* )&cliaddr , &clilen );

            printf("start to read: \n");
						//sav fd to client[i]
            for(i = 0 ; i<FD_SETSIZE; i++){
                if(client[i]<0) {
                    client[i] = connfd;
                    break;
                }
						}
            //if full, exit
						if(i == FD_SETSIZE){
                printf("too many client\n");
                exit(0);
            }
						//wait connfd when select
            FD_SET(connfd, &allset);
            if(connfd > maxfd )maxfd = connfd;
            if(i > maxi )maxi = i;
            if(--nready <= 0)continue;
        }
				//seek connected socket
				for(i=0;i<=maxi;i++){
            if( (sockfd = client[i]) < 0 )continue;
            if(FD_ISSET(sockfd,&rset)){
                if((n = readline(sockfd , buf , MAXLINE )) == 0 )
                {
                    close(sockfd);
                    FD_CLR(sockfd , &allset );
                    client[i] = -1;
                }
                else if(n>0){
									int k;
									//write messege to all client
									printf("%s",buf);
									for(k=0;k<=maxi;k++){
										if(client[k]!=-1){
											printf("write in k=%d\n",k);
											if((write(client[k] , buf , n))!=n)printf("write error!\n");
										}
									}
                }
								else if (n<0)printf("error!\n");	
								if(--nready <= 0) break;
            }

        }

    }


}
Example #10
0
int
main(int argc, char ** argv)
{
    int listenfd, connfd, i, maxindex;
    int n, nready;
    int client[MAXCLIENT];
    fd_set rset;
    int maxfds;
    char buf[MAXLINE];
    struct sockaddr_in svraddr, cliaddr;
    svraddr.sin_family = AF_INET;
    svraddr.sin_port = htons(SEVR_PORT);
    svraddr.sin_addr.s_addr = htonl(INADDR_ANY);

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    Bind(listenfd, (struct sockaddr *)&svraddr, sizeof(svraddr));
    Listen(listenfd, 17);
    Signal(SIGCHLD, sig_child);
    FD_ZERO(&rset);
    maxfds = listenfd + 1;
    socklen_t clilen = sizeof(cliaddr);

    for(i=0; i<MAXCLIENT; i++)
        client[i] = -1;
    maxindex = 0;
    for(;;)
    {
        FD_SET(listenfd, &rset);
        nready = Select(maxfds, &rset, NULL, NULL, NULL);
        if( FD_ISSET(listenfd, &rset) )
        {
            connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
            printf("Accept Connection from %s %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, buf, sizeof(cliaddr)), ntohs(cliaddr.sin_port));
            maxfds = MAX(maxfds, connfd) + 1;
            for(i=0; i<MAXCLIENT; i++)
            {
                if( client[i] < 0 )
                {
                    client[i] = connfd;
                    break;
                }
            }
            if( i == MAXCLIENT )
                err_quit("too many clients");
            FD_SET(connfd, &rset);
            maxfds = MAX(maxfds, connfd) + 1;
            maxindex = MAX(maxindex, i);   //record max index of client valid
        }

        for(i=0; i<maxindex; i++)
        {
            int sockfd;
            if( (sockfd = client[i]) < 0 )    //find valid socket fd
                continue;

            printf("sockfd = %d\n", sockfd);
            if( FD_ISSET(sockfd, &rset) )
            {
                printf("client FD_ISSET\n");
                if( (n = read(sockfd, buf, MAXLINE)) == 0 ) // read EOF
                {
                     close(sockfd);
                     FD_CLR(sockfd, &rset);
                     client[i] = -1;
                }
                else
                    writen(sockfd, buf, n);
            }
            if( -- nready == 0 )
                break;  //process all readable socket fd
        }
    }

}
Example #11
0
int main() {
    fd_set master;
    fd_set read_fds;
    struct sockaddr_in serveraddr;
    struct sockaddr_in clientaddr;
    int fdmax;
    int listener;
    int newfd;
    char buf[5000];
    int nbytes;
    int yes = 1;
    int addrlen;
    int i, j;

    FD_ZERO(&master);
    FD_ZERO(&read_fds);

    if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
      perror("Server-socket() error ");
      exit(1);
    }

    printf("Server-socket() is OK...\n");

    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = INADDR_ANY;
    serveraddr.sin_port = htons(PORT);

    memset(&(serveraddr.sin_zero), '\0', 8);

    if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) {
        perror("Server-bind() error ");
        exit(1);
    }

    printf("Server-bind() is OK...\n");

    if(listen(listener, 1000) == -1) {
         perror("Server-listen() error ");
         exit(1);
    }

    printf("Server-listen() is OK...\n");

    FD_SET(listener, &master);
    fdmax = listener;
    for(;;) {
        read_fds = master;
        if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("Server-select() error lol!");
            exit(1);
        }
        else {
          printf("Server-select() is OK...\n");
        }

        for(i = 0; i <= fdmax; i++) {
          if(FD_ISSET(i, &read_fds)) {
                if(i == listener) {
                    addrlen = sizeof(clientaddr);
                    if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1) {
                        perror("Server-accept() error");
                      }
                    else {
                        printf("Server-accept() is OK...\n");
                        FD_SET(newfd, &master);
                        if(newfd > fdmax) {
                            fdmax = newfd;
                        }

                        printf("%s: New connection on socket %d\n", inet_ntoa(clientaddr.sin_addr), newfd);
                    }
                }

                else {
                    if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
                            if(nbytes == 0)
                                printf("socket %d hung up\n", i);
                            else
                                perror("recv() error");
                            close(i);
                            FD_CLR(i, &master);
                    }
                    else {
                        for(j = 0; j <= fdmax; j++) {
                            if(FD_ISSET(j, &master)) {
                                if(j != listener && j != i) {
                                    if(send(j, buf, nbytes, 0) == -1)
                                        perror("send() error");
                                }
                            }
                        }
                    }
                }
          }
      }
  }
  return 0;
}
Example #12
0
main(int argc,char *argv[])
#endif
{
    int                 listener_fd, new_fd;
    int                 remotelen;
    int                 port = 0;
    int                 c, on;
    struct sockaddr_in  local_sin, remote_sin;
    static              fd_set  fdset, fdset_saved;
    struct conn_stat   *rconn, *wconn;
#ifdef STE_WINDOWS
    u_long              param = 0; /* FIONBIO コマンドのパラメータ Non-Blocking ON*/
    int                 nRtn;
    WSADATA             wsaData;
    stehubstat_t        stehubstat[1];
    
    nRtn = WSAStartup(MAKEWORD(1, 1), &wsaData);
#endif

    while ((c = getopt(argc, argv, "p:d:")) != EOF){
        switch (c) {
            case 'p':
                port = atoi(optarg);
                break;                
            case 'd':
                debuglevel = atoi(optarg);
                break;
            default:
                print_usage(argv[0]);
        }
    }    

    conn_stat_head->next = NULL;
    conn_stat_head->fd = 0;

    if(( listener_fd = socket( AF_INET, SOCK_STREAM,0 )) < 0 ) {
        SET_ERRNO();
        print_err(LOG_ERR,"socket: %s (%d)\n", strerror(errno), errno);
        exit(1);
    }

    on = 1;
    if((setsockopt(listener_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) <0){
        SET_ERRNO();        
        print_err(LOG_ERR,"setsockopt:%s\n", strerror(errno));                
        exit(1);
    }

    if(port == 0)
        port = PORT_NO;
    memset((char *)&remote_sin, 0x0, sizeof(struct sockaddr_in));
    memset((char *)&local_sin, 0x0, sizeof(struct sockaddr_in));
    local_sin.sin_port   = htons((short)port);
    local_sin.sin_family = AF_INET;
    local_sin.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(listener_fd,(struct sockaddr *)&local_sin,sizeof(struct sockaddr_in)) < 0 ){
        SET_ERRNO();
        print_err(LOG_ERR,"bind:%s\n", strerror(errno));                        
        exit(1);
    }

    /*
     * accept() でブロックされるのを防ぐため、non-blocking mode に設定
     */
#ifndef STE_WINDOWS            
    if( fcntl (listener_fd, F_SETFL, O_NONBLOCK) < 0) {
#else
    if( ioctlsocket(listener_fd, FIONBIO, &param) < 0){
#endif                
        SET_ERRNO();
        print_err(LOG_ERR, "Failed to set nonblock: %s (%d)\n",strerror(errno), errno);
        exit(1);
    }

    if(listen(listener_fd, 5) < 0) {
        SET_ERRNO();
        print_err(LOG_ERR,"listen:%s\n", strerror(errno));                                
        exit(1);
    }

    FD_ZERO(&fdset_saved);
    FD_SET(listener_fd, &fdset_saved);

    /*
     * syslog のための設定。Facility は LOG_USER とする
     * Windows の場合はログファイルをオープンする。
     */
#ifdef STE_WINDOWS
    hStedLog = CreateFile(STEHUB_LOG_FILE,
                          GENERIC_READ|GENERIC_WRITE,
                          FILE_SHARE_READ| FILE_SHARE_WRITE,
                          NULL,
                          CREATE_ALWAYS,
                          FILE_ATTRIBUTE_NORMAL,
                          NULL);
    SetFilePointer(hStedLog, 0, NULL, FILE_END);

    if(isTerminal == FALSE){
        /* サービスとして呼ばれている(コマンドプロンプトから呼ばれていない)場合 */
        stehubServiceStatus.dwServiceType = SERVICE_WIN32;
        stehubServiceStatus.dwCurrentState = SERVICE_START_PENDING;
        stehubServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
        stehubServiceStatus.dwWin32ExitCode = 0;
        stehubServiceStatus.dwServiceSpecificExitCode = 0;
        stehubServiceStatus.dwCheckPoint = 0;
        stehubServiceStatus.dwWaitHint = 0;
    
        /* サービスコントロールハンドラーを登録 */
        stehubServiceStatusHandle = RegisterServiceCtrlHandlerEx(
            "Stehub",                //LPCTSTR
            stehub_svc_ctrl_handler, //LPHANDLER_FUNCTION_EX
            (LPVOID)stehubstat       //LPVOID 
            );

        if (stehubServiceStatusHandle == (SERVICE_STATUS_HANDLE)0){
            return;
        }
    
        stehubServiceStatus.dwCurrentState = SERVICE_RUNNING;
        stehubServiceStatus.dwCheckPoint = 0;
        stehubServiceStatus.dwWaitHint = 0;
    
        if (!SetServiceStatus (stehubServiceStatusHandle, &stehubServiceStatus)){
            // SetServiceStatus が失敗した場合の処理・・        
            print_err(LOG_ERR, "SetServiceStatus Failed\n");
        }
    }
#else
     openlog(basename(argv[0]),LOG_PID,LOG_USER);
#endif
     
    /*
     * ここまではとりあえず、フォアグラウンドで実行。
     * ここからは、デバッグレベル 0 (デフォルト)なら、バックグラウンド
     * で実行し、そうでなければフォアグラウンド続行。
     * Windows の場合は、いづれにしてもフォアグラウンドで実行
     * し、デバッグレベル 1 以上の場合はログをファイルに書く。
     */
    if (debuglevel == 0){
#ifndef STE_WINDOWS             
        print_err(LOG_NOTICE,"Going to background mode\n");
        if(become_daemon() != 0){
            print_err(LOG_ERR,"can't become daemon\n");
            print_err(LOG_ERR,"Exit\n");            
            exit(1);
        }
#else 
        use_log = 1;
#endif    
    }
    print_err(LOG_NOTICE,"Started\n");        

    /*
     * メインループ
     * 仮想 NIC デーモンからの接続要求を待ち、接続後は仮想 NIC デーモン
     * からのデータを待つ。1つの仮想デーモンからのデータを他方に転送する。
     */
    for(;;){
        fdset = fdset_saved;
        if( select(FD_SETSIZE, &fdset, NULL, NULL, NULL) < 0){
            SET_ERRNO();
            print_err(LOG_ERR,"select:%s\n", strerror(errno));
        }

        if(FD_ISSET(listener_fd, &fdset)){
            remotelen = sizeof(struct sockaddr_in);
            if((new_fd = accept(listener_fd,(struct sockaddr *)&remote_sin, &remotelen)) < 0){
                SET_ERRNO();
                if(errno == EINTR || errno == EWOULDBLOCK || errno == ECONNABORTED){
                    print_err(LOG_NOTICE, "accept: %s\n", strerror(errno));
                    continue;
                } else {
                    print_err(LOG_ERR, "accept: %s\n", strerror(errno));                    
                    return(-1);
                }
            }
            
            FD_SET(new_fd, &fdset_saved);
            print_err(LOG_NOTICE,"fd%d: connection from %s\n",new_fd, inet_ntoa(remote_sin.sin_addr));
            add_conn_stat(new_fd, remote_sin.sin_addr);
            /*
             * recv() でブロックされるのを防ぐため、non-blocking mode に設定
             */
#ifndef STE_WINDOWS            
            if (fcntl(new_fd, F_SETFL, O_NONBLOCK) < 0 ) {
#else
                if(ioctlsocket(new_fd, FIONBIO, &param) < 0){
#endif                
                    SET_ERRNO();
                    print_err(LOG_ERR, "fd%d: Failed to set nonblock: %s (%d)\n",
                              new_fd,strerror(errno),errno);
                    return(-1);
                }
                continue;
            }

            for( rconn = conn_stat_head->next ; rconn != NULL ; rconn = rconn->next){
                int rfd, wfd;

                rfd = rconn->fd;
            
                if (FD_ISSET(rfd, &fdset)){
                    int   rsize;
                    char  databuf[SOCKBUFSIZE];
                    char *bufp;
                    int   datalen;

                    bufp = (char *)databuf;
                    rsize = recv(rfd, bufp, SOCKBUFSIZE,0);
                    if(rsize == 0){
                        /*
                         * コネクションが切断されたようだ。
                         * socket を close してループを抜ける
                         */
                        print_err(LOG_ERR,"fd%d: Connection closed by %s\n", rfd, inet_ntoa(rconn->addr));
                        CLOSE(rfd);
                        print_err(LOG_ERR,"fd%d: closed\n", rfd);
                        FD_CLR(rfd, &fdset_saved);
                        delete_conn_stat(rfd);
                        break;
                    }
                    if(rsize < 0){
                        SET_ERRNO();                    
                        /*
                         * 致命的でない error の場合は無視してループを継続
                         */
                        if(errno == EINTR || errno == EWOULDBLOCK){
                            print_err(LOG_NOTICE, "fd%d: recv: %s\n", rfd, strerror(errno));
                            continue;
                        }
                        /*
                         * エラーが発生したようだ。
                         * socket を close して forループを抜ける
                         */
                        print_err(LOG_ERR,"fd%d: recv: %s\n", rfd,strerror(errno));
                        CLOSE(rfd);
                        print_err(LOG_ERR,"fd%d: closed\n", rfd);
                        FD_CLR(rfd, &fdset_saved);
                        delete_conn_stat(rfd);
                        break;
                    }
                    /*
                     * 他の仮想 NIC にパケットを転送する。
                     * 「待ち」が発生すると、パフォーマンスに影響があるので、EWOULDBLOCK
                     *  の場合は配送をあきらめる。
                     */
                    for(wconn = conn_stat_head->next ; wconn != NULL ; wconn = wconn->next){
                    
                        wfd = wconn->fd;

                        if (rfd == wfd)
                            continue;

                        if( debuglevel > 1){
                            print_err(LOG_ERR,"fd%d(%s) ==> ", rfd, inet_ntoa(rconn->addr));
                            print_err(LOG_ERR,"fd%d(%s)\n", wfd,inet_ntoa(wconn->addr));
                        }
                
                        if ( send(wfd, bufp, rsize, 0) < 0){
                            SET_ERRNO();                    
                            if(errno == EINTR || errno == EWOULDBLOCK ){
                                print_err(LOG_NOTICE,"fd%d: send: %s\n", wfd ,strerror(errno));
                                continue;
                            } else {
                                print_err(LOG_ERR,"fd%d: send: %s (%d)\n",wfd,strerror(errno), errno);
                                CLOSE(wfd);
                                print_err(LOG_ERR,"fd%d: closed\n", wfd);
                                FD_CLR(wfd, &fdset_saved);
                                delete_conn_stat(wfd);
                                break;                            
                            }
                        }                    
                    } /* End of loop for send()ing */
                }
            } /* End of loop for each connection */
        } /* End of main loop */
}

#ifdef STE_WINDOWS
/**************************************************************************
 * Windows の場合の main()
 * 
 * 引数が -I もしくは -U だった場合には本プログラム(仮想 HUB デーモン)
 * を Windows のサービスとして登録/登録解除する。
 * それ以外の引数が渡された場合には ste_svc_main() を直接呼び出し、引数も
 * そのまま ste_svc_main() に渡す。
 * 
 * 引数(argvとして):
 * 
 *      -I : サービスとして登録。
 *      -U : 登録解除
 * 
 **************************************************************************/
int WINAPIV
main(int argc, char *argv[])
{
    int c;

    SERVICE_TABLE_ENTRY  DispatchTable[] = {
        {  "Stehub", stehub_svc_main},
        {  NULL,   NULL         }
    };

    isTerminal = _isatty(_fileno(stdout))? TRUE:FALSE;    

    //
    // 引数が無ない場合。
    // コマンドプロンプトから呼ばれた時は stehub_svc_main() を呼び、
    // そうでなければ StartServiceCtlDispatcher() を呼ぶ。
    //
    if(argc == 1 ){
        if(isTerminal == TRUE){
            stehub_svc_main(argc, argv);
            return(0);
        } else {
            StartServiceCtrlDispatcher(DispatchTable);
            return(0);
        }
    }
    
    while((c = getopt(argc, argv, "IU")) != EOF ){        
        switch(c){
            case 'I':
                // stehub.exe をサービスとして登録
                if(stehub_install_svc())
                    printf("Service Installed Sucessfully\n");
                else
                    printf("Error Installing Service\n");
                break;
            case 'U':
                // stehub.exe のサービスとして登録を解除
                if(stehub_delete_svc())
                    printf("Service UnInstalled Sucessfully\n");
                else
                    printf("Error UnInstalling Service\n");
                break;
            default :
                //
                // 引数が -U、-I でなければコマンドプロンプト内で
                // stehub.exe を起動したいのだと判断し、引数を全て
                // stehub_svc_main() に渡して呼び出す。
                //
                stehub_svc_main(argc, argv);
                return(0);
        }
    }
    return(0);    
}

/****************************************
 * Windows サービス登録ルーチン
 * 
 ****************************************/
BOOL stehub_install_svc()
{
    LPCTSTR lpszBinaryPathName;
    TCHAR strDir[1024];
    HANDLE schSCManager,schService;
    
    GetCurrentDirectory(1024, strDir);
    strcat((char *)strDir, "\\stehub.exe"); 
    schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

    if (schSCManager == NULL) 
        return FALSE;

    lpszBinaryPathName=strDir;

    schService = CreateService(schSCManager,"Stehub", 
                               "Stehub Virtual HUB daemon", // 表示用サービス名
                               SERVICE_ALL_ACCESS,        // アクセス
                               SERVICE_WIN32_OWN_PROCESS, // サービスタイプ
                               SERVICE_DEMAND_START,      // スタートタイプ
                               SERVICE_ERROR_NORMAL,      // エラーコントロールタイプ
                               lpszBinaryPathName,        // バイナリへのパス
                               NULL, // No load ordering group 
                               NULL, // No tag identifier 
                               NULL, // No dependencies
                               NULL, // LocalSystem account
                               NULL);// No password

    if (schService == NULL)
        return FALSE; 

    CloseServiceHandle(schService);
    return TRUE;
}

/****************************************
 * Windows サービス登録解除ルーチン
 * 
 ****************************************/
BOOL stehub_delete_svc()
{
    HANDLE schSCManager;
    SC_HANDLE hService;
    schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

    if (schSCManager == NULL)
        return FALSE;
    hService=OpenService(schSCManager, "Stehub", SERVICE_ALL_ACCESS);
    if (hService == NULL)
        return FALSE;
    if(DeleteService(hService)==0)
        return FALSE;
    if(CloseServiceHandle(hService)==0)
        return FALSE;

    return TRUE;
}

/******************************************************************************
 * stehub_svc_ctrl_handler()
 * 
 * サービスステータスハンドラー
 * DEVICEEVENT を拾うためには Handler ではなく、HandlerEx じゃないといけないらしい。
 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/handlerex.asp
 *
 * まったく呼ばれていないような・・?
 ******************************************************************************/
DWORD WINAPI
stehub_svc_ctrl_handler(
    DWORD dwControl,
    DWORD dwEventType,
    LPVOID lpEventData,  
    LPVOID lpContext
    )
{
    PDEV_BROADCAST_HDR  p      = (PDEV_BROADCAST_HDR) lpEventData;
    WPARAM              wParam = (WPARAM) dwEventType;
    stehubstat_t         *stehubstat = NULL;

    stehubstat = (stehubstat_t *)lpContext;

    if(debuglevel > 1){
        print_err(LOG_DEBUG, "Service Status Handler stehub_svc_ctrl_handler called\n");
    }
    
    switch(dwControl){
        case SERVICE_CONTROL_DEVICEEVENT:
            break;
        case SERVICE_CONTROL_PAUSE: 
            stehubServiceStatus.dwCurrentState = SERVICE_PAUSED;
            break;
        case SERVICE_CONTROL_CONTINUE:
            stehubServiceStatus.dwCurrentState = SERVICE_RUNNING;
            break;
        case SERVICE_CONTROL_STOP:
            stehubServiceStatus.dwWin32ExitCode = 0;
            stehubServiceStatus.dwCurrentState = SERVICE_STOPPED;
            stehubServiceStatus.dwCheckPoint = 0;
            stehubServiceStatus.dwWaitHint = 0;

            SetServiceStatus (stehubServiceStatusHandle,&stehubServiceStatus);

            break;
        case SERVICE_CONTROL_INTERROGATE:
            break; 
    }
    return NO_ERROR;
}
Example #13
0
APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
                                             const apr_pollfd_t *descriptor)
{
    apr_uint32_t i;
#ifndef HAVE_POLL
    apr_os_sock_t fd;
#endif

#ifdef HAVE_POLL
    for (i = 0; i < pollset->nelts; i++) {
        if (descriptor->desc.s == pollset->query_set[i].desc.s) {
            /* Found an instance of the fd: remove this and any other copies */
            apr_uint32_t dst = i;
            apr_uint32_t old_nelts = pollset->nelts;
            pollset->nelts--;
            for (i++; i < old_nelts; i++) {
                if (descriptor->desc.s == pollset->query_set[i].desc.s) {
                    pollset->nelts--;
                }
                else {
                    pollset->pollset[dst] = pollset->pollset[i];
                    pollset->query_set[dst] = pollset->query_set[i];
                    dst++;
                }
            }
            return APR_SUCCESS;
        }
    }

#else /* no poll */
    if (descriptor->desc_type == APR_POLL_SOCKET) {
        fd = descriptor->desc.s->socketdes;
    }
    else {
#if !APR_FILES_AS_SOCKETS
        return APR_EBADF;
#else
        fd = descriptor->desc.f->filedes;
#endif
    }

    for (i = 0; i < pollset->nelts; i++) {
        if (descriptor->desc.s == pollset->query_set[i].desc.s) {
            /* Found an instance of the fd: remove this and any other copies */
            apr_uint32_t dst = i;
            apr_uint32_t old_nelts = pollset->nelts;
            pollset->nelts--;
            for (i++; i < old_nelts; i++) {
                if (descriptor->desc.s == pollset->query_set[i].desc.s) {
                    pollset->nelts--;
                }
                else {
                    pollset->query_set[dst] = pollset->query_set[i];
                    dst++;
                }
            }
            FD_CLR(fd, &(pollset->readset));
            FD_CLR(fd, &(pollset->writeset));
            FD_CLR(fd, &(pollset->exceptset));
            if (((int)fd == pollset->maxfd) && (pollset->maxfd > 0)) {
                pollset->maxfd--;
            }
            return APR_SUCCESS;
        }
    }
#endif /* no poll */

    return APR_NOTFOUND;
}
Example #14
0
int main()
{
    struct sockaddr_in name;
    int                s;
    fd_set             mask;
    int                recv_s[10];
    int                valid[10];  
    fd_set             dummy_mask,temp_mask;
    int                i,j,num;
    int                mess_len;
    int                neto_len;
    char               mess_buf[MAX_MESS_LEN];
    long               on=1;

    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s<0) {
        perror("Net_server: socket");
        exit(1);
    }

    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
    {
        perror("Net_server: setsockopt error \n");
        exit(1);
    }

    name.sin_family = AF_INET;
    name.sin_addr.s_addr = INADDR_ANY;
    name.sin_port = htons(PORT);

    if ( bind( s, (struct sockaddr *)&name, sizeof(name) ) < 0 ) {
        perror("Net_server: bind");
        exit(1);
    }
 
    if (listen(s, 4) < 0) {
        perror("Net_server: listen");
        exit(1);
    }

    i = 0;
    int is_first = 0;
    int no_reception = 0;
    FILE * fw;
    struct timeval first, last;
    gettimeofday(&first, NULL);
    int total_bytes=0;
    FD_ZERO(&mask);
    FD_ZERO(&dummy_mask);
    FD_SET(s,&mask);
    for(;;)
    {
        temp_mask = mask;
        num = select( FD_SETSIZE, &temp_mask, &dummy_mask, &dummy_mask, NULL);
        if (num > 0) {
            if ( FD_ISSET(s,&temp_mask) ) {
                recv_s[i] = accept(s, 0, 0) ;
                FD_SET(recv_s[i], &mask);
                valid[i] = 1;
                i++;
            }
            for(j=0; j<i ; j++)
            {   if (valid[j]) {   
                if ( FD_ISSET(recv_s[j],&temp_mask) ) {
                    if (is_first == 0) {
                     is_first = 1;
                     int length;
                     if (recv(recv_s[j], &length, sizeof(length),0) > 0)                     {
                      int strlen = length - sizeof(length);
                      recv(recv_s[j], mess_buf, strlen, 0);
                      mess_buf[strlen] = '\0';
                      printf("Writing to %s\n", mess_buf);
                      gettimeofday(&first, NULL);
                      fw = fopen(mess_buf, "w");
                     }
                    }
                    int len = recv(recv_s[j],mess_buf,MAX_MESS_LEN,0);
                    if( len > 0) {
                        no_reception = 0;
                        fwrite(mess_buf, 1, len, fw);
                        total_bytes = total_bytes + len;
                     }
                      else {
                        no_reception++;
                        if (no_reception == 2) {
                          FD_CLR(recv_s[j], &mask);
                          close(recv_s[j]);
                          valid[j]=0;
                          if (fw != NULL) {
                            fclose(fw);
                          }
                          gettimeofday(&last, NULL);
                          double difference = (double)(last.tv_sec - first.tv_sec) + (double)(last.tv_usec - first.tv_usec) / 1000000.0;
                          double total = (double)total_bytes / 1000000.0;
                          printf("Transfer completed. Total Megabytes %f. Total Time %f. Average Rate (Mbits/sec) %f.\n", total, difference, (total*8.0) / difference);
                          exit(1);
                         }
                      }
                  }
               }
            }
        }
    }
    return 0;

}
Example #15
0
int main(){
	//создаем именованные каналы в ядре с местом в файловом пространстве имен
	printf("Создаю именованные каналы...");fflush(stdout);
	const char *pipe_in="in.fifo", *pipe_out="out.fifo";
	unlink(pipe_in);
	unlink(pipe_out);
	int res=mkfifo(pipe_in,0666);
	if(-1==res){
		perror("Ошибка создания канала in");
		return 1;
	}
	res=mkfifo(pipe_out,0666);
	if(-1==res){
		perror("Ошибка создания канала out");
		return 2;
	}
	printf("ok!\n");

	//получаем файловые дескрипторы каналов и переводим в неблокирующий режим (чтение и запись, чтоб не блокировалось здесь же сразу)
	printf("Получаю файловые дескрипторы...");
	int fd_in=open(pipe_in,O_RDWR|O_NONBLOCK);
	if(-1==fd_in){
		perror("Не получен дескриптор in");
		return 3;
	}
	int fd_out=open(pipe_out,O_RDWR|O_NONBLOCK);
	if(-1==fd_out){
		perror("Не получен дескриптор out");
		close(fd_in);
		return 4;
	}
	printf("ok!\n");

	//мультиплексирование
	printf("Мультиплексирование (select):\n");
	fd_set set_for_read, set_for_write;    //ровно по 1024 бит 
	printf("Цикл:\n");
	//узнаем наибольший номер дескриптора, чтоб узнать сколько битов в наборе нужно отслеживать
	int max=fd_in<fd_out ? fd_out : fd_in;
	//буфер на сервере (на случай задержки отправки)
	struct Buf *root=NULL, *tail=NULL;
	int is_out=0;
	//запускаем цикл проверки
	long long cnt=0;
	while(1){
		//инициализация
		FD_ZERO(&set_for_read); 
		FD_ZERO(&set_for_write);
		
		//добавляем в набор отслеживаемый на чтение дескриптор
		printf("\tдобавляем in...");
		FD_SET(fd_in,&set_for_read);
		printf("ok!\n");
		if(is_out){
			printf("\tдобавляем out...");
			FD_SET(fd_out,&set_for_write);
			printf("ok!\n");
		}
	        fflush(stdout);

		//запускаем проверку готовности
		++cnt;
		printf("\n%lld)-->select...",cnt);fflush(stdout);
		select(max+1,&set_for_read,&set_for_write,NULL,NULL);//эта команда сбрасывает не готовые биты поля, поэтому нужно регистрировать поновой	
		printf("ok!\n");
		//проснулись
		if(FD_ISSET(fd_out,&set_for_write)){ //проверка готовности писать
			printf("-->write...");
			if(root==NULL)
				FD_CLR(fd_out,&set_for_write);//снимаем с регистрации, т.к. нечего писать
			else{
				int len=write(fd_out,root->data,root->len);
				if(len!=-1){//успешно записано
					printf("ok!\n");
					struct Buf * tmp=root->next;
					free(root);
					root=tmp;
					if(root==NULL){ //все записано
						tail=NULL;
						is_out=0;
					}
				}
			}
		}
		if(FD_ISSET(fd_in,&set_for_read)){ //проверка готовности чтения
			printf("-->read...");
			//читаем из канала
			char data[LEN+1];
			int len=read(fd_in,data,LEN);
			if(-1!=len){
				if(root==NULL)
					tail=root=(struct Buf*)malloc(sizeof(struct Buf));
				else{
					tail->next=(struct Buf*)malloc(sizeof(struct Buf));
					tail=tail->next;
				}
				tail->next=NULL;
				tail->len=len;
				memcpy(tail->data,data,len);
				data[len]='\0';
				printf("ok! data=%s\n",data);

				//регистрируем дескриптор out
				is_out=1;
			}

		}
	}

	//закрываем дескрипторы
	close(fd_in);
	close(fd_out);

	//выносим каналы из фалового пространства
	unlink(pipe_in);
	unlink(pipe_out);
	
	return 0;
}
Example #16
0
int main(int argc, char const *argv[])
{
	if(argc!=2)
	{
		printf("Pass the fifo name\n");
		exit(1);
	}
	//sharing Process Id
	int k1=ftok(".",1);
	int shmid=shmget(k1,sizeof(int),0777|IPC_CREAT);
	if(shmid==-1)
	{
		printf("shmget error\n");
		exit(1);
	}
	int *p;
	p=shmat(shmid,NULL,0);
	if(p==(int*)-1)
	{
		printf("shmat error\n");
		exit(1);
	}
	*p=getpid();
	signal(SIGUSR1,handler);

	k1=ftok(".",3);
	shmid=shmget(k1,30,0777|IPC_CREAT);
	if(shmid==-1)
	{
		printf("shmget 1error\n");
		exit(1);
	}
	
	char *p1=shmat(shmid,NULL,0);
	if(p1==(char*)-1)
	{
		printf("shmat error\n");
		exit(1);
	}
	char *name="/tmp/";
	fifo=(char*)malloc(BUF_SIZE);
	sprintf(fifo,"%s%s",name,argv[1]);
	int r=mkfifo(fifo,0777);
	if(r<0)
	{
		printf("mkfifo error\n");
		exit(1);
	}
	strcpy(p1,fifo);

	//getting fifo name
	int pfd[5];
	k1=ftok(".",2);
	shmid=shmget(k1,30,0777|IPC_CREAT);
	if(shmid==-1)
	{
		printf("shmget error\n");
		exit(1);
	}
	char *p2;
	p2=shmat(shmid,NULL,0);
	if(p2==(char*)-1)
	{
		printf("shmat error\n");
		exit(1);
	}
	int c=0;
	int fd[2];
	pipe(fd);
	c=fork();
	strcpy(msg,"");
	if(c>0)
	{
		int nfd=4;
		pfd[0]=0;
		pfd[1]=open(p2,O_RDONLY);
		FILE *f=popen("./po","r");
		pfd[2]=fileno(f);
		close(fd[1]);
		pfd[3]=fd[0];
		int i=0,j;
		while(1)
		{
			sleep(1);
			struct timeval tv;
	        tv.tv_sec = 0;
	        tv.tv_usec = 0;
	        fd_set tr;
	        FD_ZERO(&tr);
	        FD_SET(pfd[i],&tr);
	        //printf("before\n");
	        int res=select(pfd[i]+1,&tr,NULL,NULL,&tv);
	        
	        
	        //read(pfd[i],buf,BUF_SIZE);
	        //printf("in while %d %d\n",res,i);
	        if(res>0&&FD_ISSET(pfd[i],&tr))
	        {//printf("inside event %d\n", i);
				char *buf=(char*)malloc(BUF_SIZE);	
				read(pfd[i],buf,BUF_SIZE);
				strcat(msg,"\t");
				strcat(msg,buf);
			}
			FD_CLR(pfd[i],&tr);
			i=(i+1)%nfd;
		}
	}
	else
	{
		close(fd[0]);
		while(1)
		{
			sleep(10);
			char *m="This is from pipe";
			write(fd[1],m,strlen(m));
		}
	}
	return 0;
}
Example #17
0
File: ipv6.c Project: yoanlcq/FATE
void fe_ipv6_hub_rm_udp6(fe_ipv6_hub *s, fe_udp6 *sock) {
    if(!FD_ISSET(*sock, &s->read_set))
        return;
    FD_CLR(*sock, &s->read_set);
    FD_CLR(*sock, &s->ready_set);
}
Example #18
0
/*
 * Servers that echoes a Client using I/O Multiplexing
 */
int main(int argc, char **argv) {

    // Check arguments
    if (argc != 2){
        printf("Usage: ./echosrv <PORT>\n");
        return -1; 
    }

    // Create the socket
    int listenfd;
    if ((listenfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
        perror("socket\n");
        return -1;
    }

    // Initialize server sockaddr structure
    struct sockaddr_in6 servaddr;
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin6_family = AF_INET6;
	servaddr.sin6_addr = in6addr_any;
	servaddr.sin6_port = htons(atoi(argv[1]));

	if ((bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0) {
        perror("bind");
        return -1;
    }

    // Convert the socket to a listening socket
	if (listen(listenfd, BACKLOG) < 0 ) {
        perror("listen");
        return -1;
    }

    // Initialize arguments for the select function
    int maxfd = listenfd;
    
    // Initialize the array of clients
    int client[FD_SETSIZE];
    for (int i = 0; i < FD_SETSIZE; i++) {
        client[i] = -1;
    }

    // Initialize the array of client nicknames
    int nicknames[FD_SETSIZE][MAXNICK];
    
    // Initialize all descriptors
    fd_set rset;
    fd_set allset;
    FD_ZERO(&allset);
    FD_SET(listenfd, &allset);

    // Ready descriptors
    int ready;
    int connfd;
    int sockfd;
    int i;
    int n;
    struct sockaddr_in6 cliaddr;
    socklen_t clilen = sizeof(cliaddr);
    char buff[MAXLINE];
    char temp[MAXLINE];
    char addrbuff[INET6_ADDRSTRLEN];
    while (1) {
        rset = allset;
        if ((ready = select(maxfd + 1, &rset, NULL, NULL, NULL)) < 0) {
            perror("select");
            return -1;
        }

        // Check for new client
        if (FD_ISSET(listenfd, &rset)) {
            if ((connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0) {
                perror("accept");
                return -1;
            }
            // Convert IPv6 address to presentation
            inet_ntop(AF_INET6, &cliaddr.sin6_addr, addrbuff, INET6_ADDRSTRLEN);
            printf("Connected client from %s:%d\n", addrbuff, ntohs(cliaddr.sin6_port));

            // Save connected socket descriptor in the client array
            for (i = 0; i < FD_SETSIZE; i++) {
                if (client[i] < 0) {
                    client[i] = connfd;
                    break;
                }
            }

            // Ragequit on too many requests
            if (i == FD_SETSIZE) {
                printf("Too many clients\n");
                return -1;
            }

            // Add connfd to allset
            FD_SET(connfd, &allset);
            if (connfd > maxfd) {
                maxfd = connfd;
            }

            // Check whether there aren't other ready sockets
            if (--ready <= 0) {
                continue;
            }
        }

        // Serve clients
        for (i = 0; i < FD_SETSIZE; i++) {
            if ((sockfd = client[i]) < 0) {
                continue;
            }

            if (FD_ISSET(sockfd, &rset)) {
                if ((n = exso_readln(sockfd, buff, MAXLINE)) < 0) {
                    perror("exso_readln");
                }
                else if (n == 0) {
                    // Convert IPv6 address to presentation
                    inet_ntop(AF_INET6, &cliaddr.sin6_addr, addrbuff, INET6_ADDRSTRLEN);
                    printf("Disconnected client from %s:%d\n", addrbuff, ntohs(cliaddr.sin6_port));
                    
                    close(sockfd);
                    FD_CLR(sockfd, &allset);
                    client[i] = -1;
                    bzero(nicknames[i], MAXNICK);
                } else {
                    if (nicknames[i][0] == 0) {
                        if (strncmp(buff, "/nickname", 9) == 0) {
                            sscanf(buff, "/nickname %s\n", nicknames[i]);
                            sprintf(buff, "%s has joined the chat\n", nicknames[i]);
                        } else {
                            sprintf(buff, "Error, expecting /nickname <NICKNAME>\n");
                            exso_writen(client[i], buff, strlen(buff));
                            continue;
                        }
                    } else {
                        sprintf(temp, "%s: %s", nicknames[i], buff);
                        sprintf(buff, "%s", temp);
                    }
                    for (i = 0; i < FD_SETSIZE; i++) {
                        if (sockfd == client[i] || client[i] == -1) {
                            continue;
                        }
                        if (exso_writen(client[i], buff, strlen(buff)) < 0) {
                            perror("exso_writen");
                        }
                    }
                }

                // Check whether there aren't other ready sockets
                if (--ready <= 0) {
                    break;
                }
            }
        }
    }
}
Example #19
0
File: loop.c Project: hotbig/apue
void loop(void)
{
    int i, n, maxfd, maxi, listenfd, clifd, nread;
    char buf[MAXLINE];

    uid_t uid;
    fd_set rset, allset;

    FD_ZERO(&allset);

    if((listenfd = serv_listen(CS_OPEN))<0)
    {
        printf("serv_listen error\n");
        exit(2);
    }

    FD_SET(listenfd, &allset);
    maxfd = listenfd;
    maxi = -1;

    for(;;){
        rset = allset;
        if((n = select(maxfd + 1, &rset, NULL, NULL, NULL))<0)
        {
            printf("select error\n");
            exit(2);
        }
        
        if(FD_ISSET(listenfd, &rset)){
            if((clifd = serv_accept(listenfd, &uid))<0)
            {
                printf("serv accept error: %d\n", clifd);
                exit(2);
            }
            i = client_add(clifd, uid);
            FD_SET(clifd, &allset);
            if(clifd > maxfd)
                maxfd = clifd;
            if(i > maxi)
                maxi = i;
            printf("new connection: uid %d, fd %d", uid, clifd);
            continue;
        }

        for(i = 0; i<=maxi; i++){
            if((clifd = client[i].fd) < 0)
                continue;
            if(FD_ISSET(clifd, &rset)){
                if((nread = read(clifd, buf, MAXLINE)) < 0){
                    printf("read error on fd %d", clifd);
                    exit(2);
                }
                else if(nread == 0)
                {
                    printf("closed: uid %d, fd %d", client[i].uid, clifd);
                    client_del(clifd);
                    FD_CLR(clifd, &allset);
                    close(clifd);
                }
                else
                {
                    handle_request(buf, nread, clifd, client[i].uid);
                }
            }
        }
    }
}
Example #20
0
void                                   *
socket_thread_fct (
  void *arg)
{
  int                                     ret;
  struct sockaddr_in                      si_me;
  socket_data_t                          *socket_data;
  int                                     retry = SOCKET_NB_CONNECT_RETRY;

  /*
   * master file descriptor list
   */
  fd_set                                  master_fds;

  /*
   * temp file descriptor list for select()
   */
  fd_set                                  read_fds;
  int                                     fd_max = 0;
  struct timeval                          tv;

  socket_data = (socket_data_t *) arg;
  g_assert (socket_data != NULL);

  /*
   * Preparing the socket
   */
  if ((socket_data->sd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
    g_warning ("socket failed: %s", g_strerror (errno));
    free (socket_data->ip_address);
    free (socket_data);
    pthread_exit (NULL);
  }

  memset ((void *)&si_me, 0, sizeof (si_me));
  si_me.sin_family = AF_INET;
  si_me.sin_port = htons (socket_data->port);

  if (inet_aton (socket_data->ip_address, &si_me.sin_addr) == 0) {
    g_warning ("inet_aton() failed\n");
    free (socket_data->ip_address);
    free (socket_data);
    pthread_exit (NULL);
  }

  /*
   * clear the master and temp sets
   */
  FD_ZERO (&master_fds);
  FD_ZERO (&read_fds);
  /*
   * Add the GUI pipe to the list of sockets to monitor
   */
  FD_SET (socket_data->pipe_fd, &master_fds);
  /*
   * Add the client socket to the list of sockets to monitor
   */
  FD_SET (socket_data->sd, &master_fds);
  /*
   * Update the fd_max with the MAX of socket/pipe
   */
  fd_max = MAX (socket_data->pipe_fd, socket_data->sd);
  /*
   * Setup the timeout for select.
   * * * When a timeout is caught, check for new notifications to send to GUI.
   */
  tv.tv_sec = 0;
  tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING;

  do {
    /*
     * Connecting to remote peer
     */
    ret = connect (socket_data->sd, (struct sockaddr *)&si_me, sizeof (struct sockaddr_in));

    if (ret < 0) {
      if ((socket_abort_connection) || (retry < 0)) {
        if (retry < 0) {
          g_warning ("Failed to connect to peer %s:%d", socket_data->ip_address, socket_data->port);
          ui_pipe_write_message (socket_data->pipe_fd, UI_PIPE_CONNECTION_FAILED, NULL, 0);
        }

        free (socket_data->ip_address);
        free (socket_data);
        socket_abort_connection = FALSE;
        /*
         * Quit the thread
         */
        pthread_exit (NULL);
      }

      usleep (SOCKET_US_BEFORE_CONNECT_RETRY);
      retry--;
    }
  } while (ret < 0);

  /*
   * Set the socket as non-blocking
   */
  fcntl (socket_data->sd, F_SETFL, O_NONBLOCK);

  while (1) {
    memcpy (&read_fds, &master_fds, sizeof (master_fds));
    ret = select (fd_max + 1, &read_fds, NULL, NULL, &tv);

    if (ret < 0) {
      g_warning ("Error in select: %s", g_strerror (errno));
      free (socket_data->ip_address);
      free (socket_data);
      /*
       * Quit the thread
       */
      pthread_exit (NULL);
    } else if (ret == 0) {
      /*
       * Timeout for select: check if there is new incoming messages
       * * * since last GUI update
       */
      if (socket_data->nb_signals_since_last_update > 0) {
        g_debug ("Timout on select and data new signal in list");
        g_debug ("-> notify GUI");
        socket_notify_gui_update (socket_data);
      }

      /*
       * Reset the timeval to the max value
       */
      tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING;
    }

    /*
     * Checking if there is data to read from the pipe
     */
    if (FD_ISSET (socket_data->pipe_fd, &read_fds)) {
      FD_CLR (socket_data->pipe_fd, &read_fds);
      pipe_read_message (socket_data);
    }

    /*
     * Checking if there is data to read from the socket
     */
    if (FD_ISSET (socket_data->sd, &read_fds)) {
      FD_CLR (socket_data->sd, &read_fds);
      socket_read (socket_data);

      /*
       * Update the timeout of select if there is data not notify to GUI
       */
      if (socket_data->nb_signals_since_last_update > 0) {
        gint64                                  current_time;

        current_time = g_get_monotonic_time ();

        if ((current_time - socket_data->last_data_notification) > SOCKET_MS_BEFORE_SIGNALLING) {
          socket_notify_gui_update (socket_data);
          tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING;
        } else {
          /*
           * Update tv
           */
          tv.tv_usec = (1000 * SOCKET_MS_BEFORE_SIGNALLING) - (current_time - socket_data->last_data_notification);
        }
      }
    }
  }

  return NULL;
}
Example #21
0
int main(void)
{
    fd_set master;    // master file descriptor list
    fd_set read_fds;  // temp file descriptor list for select()
    int fdmax;        // maximum file descriptor number

    int listener;     // listening socket descriptor
    int newfd;        // newly accept()ed socket descriptor
    struct sockaddr_storage remoteaddr; // client address
    socklen_t addrlen;

    char buf[256];    // buffer for client data
    uint32_t recvId;
    int nbytes;
    int talking[100]= {0};  //talk to who pairs

    char remoteIP[INET6_ADDRSTRLEN];

    int yes=1;        // for setsockopt() SO_REUSEADDR, below
    int i, j, rv;

    struct addrinfo hints, *ai, *p;

    FD_ZERO(&master);    // clear the master and temp sets
    FD_ZERO(&read_fds);

    // get us a socket and bind it
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
        fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
        exit(1);
    }
    
    for(p = ai; p != NULL; p = p->ai_next) {
        listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (listener < 0) { 
            continue;
        }
        
        // lose the pesky "address already in use" error message
        setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

        if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
            close(listener);
            continue;
        }

        break;
    }

    // if we got here, it means we didn't get bound
    if (p == NULL) {
        fprintf(stderr, "selectserver: failed to bind\n");
        exit(2);
    }

    freeaddrinfo(ai); // all done with this

    // listen
    if (listen(listener, 10) == -1) {
        perror("listen");
        exit(3);
    }
    printf("server: waiting for connections...\n");

    // add the listener to the master set
    FD_SET(listener, &master);

    // keep track of the biggest file descriptor
    fdmax = listener; // so far, it's this one

    // main loop
    for(;;) {
        read_fds = master; // copy it
        if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("select");
            exit(4);
        }

        // run through the existing connections looking for data to read
        for(i = 0; i <= fdmax; i++) {
            if (FD_ISSET(i, &read_fds)) { // we got one!!
                if (i == listener) {
                    // handle new connections
                    addrlen = sizeof remoteaddr;
                    newfd = accept(listener,
                        (struct sockaddr *)&remoteaddr,
                        &addrlen);

                    if (newfd == -1) {
                        perror("accept");
                    } else {
                        FD_SET(newfd, &master); // add to master set
                        if (newfd > fdmax) {    // keep track of the max
                            fdmax = newfd;
                        }
                        printf("selectserver: new connection from %s on "
                            "socket %d\n",
                            inet_ntop(remoteaddr.ss_family,
                                get_in_addr((struct sockaddr*)&remoteaddr),
                                remoteIP, INET6_ADDRSTRLEN),
                            newfd);
                        //ask who to talk to
                        char *str="you're online now\n";
                        send(newfd, str, strlen(str), 0);
                        //show list
                        //send mesage to someone
                    }
                } else {
                    // handle data from a client
                    //recv
                    //switch cmd
                    //show -> list all
                    //talk -> get id, and pair with each other
                    if ((nbytes = recv(i, &buf, sizeof buf, 0)) <= 0) {
                        // got error or connection closed by client
                        if (nbytes == 0) {
                            // connection closed
                            printf("selectserver: socket %d hung up\n", i);
                        } else {
                            perror("recv");
                        }
                        close(i); // bye!
                        FD_CLR(i, &master); // remove from master set
                    } else {
                        // split cmd
                        char *cmd;
                        cmd= strtok(buf, " ");
                        if (strncmp(cmd, "show",4) == 0) 
                        {
                           listUsers(i,j, fdmax, master, listener);
                        } 
                        else if (strncmp(cmd, "talk",4) == 0)
                        {
                            cmd= strtok(NULL, " ");
                            //get the userId
                            int userId= atoi(cmd);
                            //get the msg
                            char *msg= strtok(NULL, " ");

                            //send the msg
                            if (FD_ISSET(userId, &master)) {
                                // except the listener and ourselves
                                if (send(userId, msg, strlen(msg), 0) == -1) {
                                    perror("send");
                                }
                            }
                            
                        }
                        else
                        {
                        }
                    }
                    

                } // END handle data from client
            } // END got new incoming connection
        } // END looping through file descriptors
    } // END for(;;)--and you thought it would never end!
    
    return 0;
}
Example #22
0
int main(int argc, char **argv) {
#ifndef THREADED
    fd_set rfds, wfds, efds;
    int processed=0;
#endif
    char buffer[4096];
    char p[2048];
#ifdef YCA
    char *cert=0;
    char appId[64];
#endif
    int bufoff = 0;
    int flags, i;
    FILE *fh;

    if (argc < 2) {
        fprintf(stderr,
                "USAGE %s zookeeper_host_list [clientid_file|cmd:(ls|ls2|create|create2|od|...)]\n", 
                argv[0]);
        fprintf(stderr,
                "Version: ZooKeeper cli (c client) version %d.%d.%d\n", 
                ZOO_MAJOR_VERSION,
                ZOO_MINOR_VERSION,
                ZOO_PATCH_VERSION);
        return 2;
    }
    if (argc > 2) {
      if(strncmp("cmd:",argv[2],4)==0){
        size_t cmdlen = strlen(argv[2]);
        if (cmdlen > sizeof(cmd)) {
          fprintf(stderr,
                  "Command length %zu exceeds max length of %zu\n",
                  cmdlen,
                  sizeof(cmd));
          return 2;
        }
        strncpy(cmd, argv[2]+4, sizeof(cmd));
        batchMode=1;
        fprintf(stderr,"Batch mode: %s\n",cmd);
      }else{
        clientIdFile = argv[2];
        fh = fopen(clientIdFile, "r");
        if (fh) {
            if (fread(&myid, sizeof(myid), 1, fh) != sizeof(myid)) {
                memset(&myid, 0, sizeof(myid));
            }
            fclose(fh);
        }
      }
    }

    flags = 0;
    for (i = 1; i < argc; ++i) {
      if (strcmp("-r", argv[i]) == 0) {
        flags = ZOO_READONLY;
        break;
      }
    }

#ifdef YCA
    strcpy(appId,"yahoo.example.yca_test");
    cert = yca_get_cert_once(appId);
    if(cert!=0) {
        fprintf(stderr,"Certificate for appid [%s] is [%s]\n",appId,cert);
        strncpy(p,cert,sizeof(p)-1);
        free(cert);
    } else {
      fprintf(stderr,"Certificate for appid [%s] not found\n",appId);
      strcpy(p,"dummy");
    }
#else
    strcpy(p, "dummy");
#endif
    verbose = 0;
    zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
    zoo_deterministic_conn_order(1); // enable deterministic order
    hostPort = argv[1];
    zh = zookeeper_init(hostPort, watcher, 30000, &myid, NULL, flags);
    if (!zh) {
        return errno;
    }

#ifdef YCA
    if(zoo_add_auth(zh,"yca",p,strlen(p),0,0)!=ZOK)
    return 2;
#endif

#ifdef THREADED
    while(!shutdownThisThing) {
        int rc;
        int len = sizeof(buffer) - bufoff -1;
        if (len <= 0) {
            fprintf(stderr, "Can't handle lines that long!\n");
            exit(2);
        }
        rc = read(0, buffer+bufoff, len);
        if (rc <= 0) {
            fprintf(stderr, "bye\n");
            shutdownThisThing=1;
            break;
        }
        bufoff += rc;
        buffer[bufoff] = '\0';
        while (strchr(buffer, '\n')) {
            char *ptr = strchr(buffer, '\n');
            *ptr = '\0';
            processline(buffer);
            ptr++;
            memmove(buffer, ptr, strlen(ptr)+1);
            bufoff = 0;
        }
    }
#else
    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    FD_ZERO(&efds);
    while (!shutdownThisThing) {
        int fd;
        int interest;
        int events;
        struct timeval tv;
        int rc;
        zookeeper_interest(zh, &fd, &interest, &tv);
        if (fd != -1) {
            if (interest&ZOOKEEPER_READ) {
                FD_SET(fd, &rfds);
            } else {
                FD_CLR(fd, &rfds);
            }
            if (interest&ZOOKEEPER_WRITE) {
                FD_SET(fd, &wfds);
            } else {
                FD_CLR(fd, &wfds);
            }
        } else {
            fd = 0;
        }
        FD_SET(0, &rfds);
        rc = select(fd+1, &rfds, &wfds, &efds, &tv);
        events = 0;
        if (rc > 0) {
            if (FD_ISSET(fd, &rfds)) {
                events |= ZOOKEEPER_READ;
            }
            if (FD_ISSET(fd, &wfds)) {
                events |= ZOOKEEPER_WRITE;
            }
        }
        if(batchMode && processed==0){
          //batch mode
          processline(cmd);
          processed=1;
        }
        if (!processed && FD_ISSET(0, &rfds)) {
            int rc;
            int len = sizeof(buffer) - bufoff -1;
            if (len <= 0) {
                fprintf(stderr, "Can't handle lines that long!\n");
                exit(2);
            }
            rc = read(0, buffer+bufoff, len);
            if (rc <= 0) {
                fprintf(stderr, "bye\n");
                break;
            }
            bufoff += rc;
            buffer[bufoff] = '\0';
            while (strchr(buffer, '\n')) {
                char *ptr = strchr(buffer, '\n');
                *ptr = '\0';
                processline(buffer);
                ptr++;
                memmove(buffer, ptr, strlen(ptr)+1);
                bufoff = 0;
            }
        }
        zookeeper_process(zh, events);
    }
#endif
    if (to_send!=0)
        fprintf(stderr,"Recvd %d responses for %d requests sent\n",recvd,sent);
    zookeeper_close(zh);
    return 0;
}
Example #23
0
int main()
{
    struct sockaddr_in sa_udp, sa_recv, sa_client, sa_udp_cl;
    socklen_t sa_udp_len    = sizeof(struct sockaddr_in);
    socklen_t sa_recv_len   = sa_udp_len;
    socklen_t sa_client_len = sa_udp_len;
    socklen_t sa_udp_cl_len = sa_udp_len;
    int udp_sock, recv_sock, client_sock, maxfd = -1;
    int udp_port = 47624, recv_port = 2350;
    unsigned char temp[512];
    int i, ret = 0;
    fd_set recv_set, master_set;

    FD_ZERO(&recv_set);
    FD_ZERO(&master_set);

    memset(&sa_udp, 0, sa_udp_len);
    memset(&sa_recv, 0, sa_recv_len);
    memset(&sa_client, 0, sa_client_len);
    memset(&sa_udp_cl, 0, sa_udp_cl_len);

    printf("Listening on udp port %d\n", udp_port);
    sa_udp.sin_family = AF_INET;
    sa_udp.sin_port = htons(udp_port);
    sa_udp.sin_addr.s_addr = htonl(INADDR_ANY);

    if((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
    {
        perror("socket");
        exit(1);
    }

    maxfd = max(maxfd, udp_sock);

    if(bind(udp_sock, (struct sockaddr *)&sa_udp, sa_udp_len) < 0)
    {
        perror("bind");
        exit(2);
    }

    FD_SET(udp_sock, &master_set);

    printf("Listening on tcp port %d\n", recv_port);
    sa_recv.sin_family = AF_INET;
    sa_recv.sin_port = htons(recv_port);
    sa_recv.sin_addr.s_addr = htonl(INADDR_ANY);

    if((recv_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
    {
        perror("socket");
        exit(3);
    }

    maxfd = max(maxfd, recv_sock);

    if(bind(recv_sock, (struct sockaddr*)&sa_recv, sa_recv_len) < 0)
    {
        perror("bind");
        exit(4);
    }

    if(listen(recv_sock, 5)< 0)
    {
        perror("listen");
        exit(5);
    }

    FD_SET(recv_sock, &master_set);

    signal(SIGINT, signal_handler);

    puts("Starting up the select loop.");

    for(;;)
    {
        recv_set = master_set;
        if(select(maxfd+1, &recv_set, NULL, NULL, NULL) < 0)
        {
            perror("select");
            exit(6);
        }
        for(i = 0; i <= maxfd; ++i)
        {
            if(FD_ISSET(i, &recv_set))
            {
                if(i == udp_sock)
                {
                    int recv_len;
                    printf("Got an udp packet!\n");
                    if((recv_len = recvfrom(udp_sock, temp, 512, 0, (struct sockaddr *)&sa_udp_cl, 
                                    &sa_udp_cl_len)) < 0)
                    {
                        perror("recvfrom");
                        exit(8);
                    }

                    if(handleSocketBroadcast(temp, recv_len, &sa_udp_cl, sa_udp_cl_len, &sa_recv) != 0)
                    {
                        fprintf(stderr, "Something bad happened in handleSocketBroadcast\n");
                    }

                    /* just throw away the rest of the data */
                    if(recv_len == 512)
                        recvfrom(udp_sock, temp, 512, 0, (struct sockaddr *)&sa_udp_cl, &sa_udp_cl_len);
                }else if(i == recv_sock)
                {
                    printf("Got a tcp packet on the server port\n");
                    if((client_sock = accept(recv_sock, (struct sockaddr *)&sa_client, &sa_client_len)) < 0)
                    {
                        perror("accept");
                        exit(7);
                    }
                    else
                    {
                        FD_SET(client_sock, &master_set);
                        maxfd = max(maxfd, client_sock);
                    }
                }
                else
                {
                    int recv_len;
                    if((recv_len = recv(i, temp, 512, 0)) < 0)
                    {
                        perror("recv");
                        exit(8);
                    }
                    if(recv_len == 0)
                    {
                        puts("Client closed socket");
                    }
                    close(i);
                    FD_CLR(i, &master_set);
                }
            }
        }
    }

    return ret;
}
Example #24
0
int main (int argc, char **argv)
{
#ifdef HAVE_LUA
	/* Lua runtime */
	lua_State *L = NULL;
#endif

	/* master file descriptor list */
	fd_set used_fds, serv_fds, read_fds;

	/* working structs */
	struct addrinfo hints;
	struct http_request *req;
	struct path_info *pin;
	struct client *cl;
	struct sigaction sa;
	struct config conf;

	/* signal mask */
	sigset_t ss;

	/* maximum file descriptor number */
	int new_fd, cur_fd, max_fd = 0;

	int tls = 0;
	int keys = 0;
	int bound = 0;
	int nofork = 0;

	/* args */
	int opt;
	char bind[128];
	char *port = NULL;

	/* library handles */
	void *tls_lib;
	void *lua_lib;

	/* clear the master and temp sets */
	FD_ZERO(&used_fds);
	FD_ZERO(&serv_fds);
	FD_ZERO(&read_fds);

	/* handle SIGPIPE, SIGINT, SIGTERM, SIGCHLD */
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);

	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, NULL);

	sa.sa_handler = uh_sigchld;
	sigaction(SIGCHLD, &sa, NULL);

	sa.sa_handler = uh_sigterm;
	sigaction(SIGINT,  &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);

	/* defer SIGCHLD */
	sigemptyset(&ss);
	sigaddset(&ss, SIGCHLD);
	sigprocmask(SIG_BLOCK, &ss, NULL);

	/* prepare addrinfo hints */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family   = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags    = AI_PASSIVE;

	/* parse args */
	memset(&conf, 0, sizeof(conf));
	memset(bind, 0, sizeof(bind));

#ifdef HAVE_TLS
	/* load TLS plugin */
	if( ! (tls_lib = dlopen("uhttpd_tls.so", RTLD_LAZY | RTLD_GLOBAL)) )
	{
		fprintf(stderr,
			"Notice: Unable to load TLS plugin - disabling SSL support! "
			"(Reason: %s)\n", dlerror()
		);
	}
	else
	{
		/* resolve functions */
		if( !(conf.tls_init   = dlsym(tls_lib, "uh_tls_ctx_init"))      ||
		    !(conf.tls_cert   = dlsym(tls_lib, "uh_tls_ctx_cert"))      ||
		    !(conf.tls_key    = dlsym(tls_lib, "uh_tls_ctx_key"))       ||
		    !(conf.tls_free   = dlsym(tls_lib, "uh_tls_ctx_free"))      ||
			!(conf.tls_accept = dlsym(tls_lib, "uh_tls_client_accept")) ||
			!(conf.tls_close  = dlsym(tls_lib, "uh_tls_client_close"))  ||
			!(conf.tls_recv   = dlsym(tls_lib, "uh_tls_client_recv"))   ||
			!(conf.tls_send   = dlsym(tls_lib, "uh_tls_client_send"))
		) {
			fprintf(stderr,
				"Error: Failed to lookup required symbols "
				"in TLS plugin: %s\n", dlerror()
			);
			exit(1);
		}

		/* init SSL context */
		if( ! (conf.tls = conf.tls_init()) )
		{
			fprintf(stderr, "Error: Failed to initalize SSL context\n");
			exit(1);
		}
	}
#endif

	while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:r:m:x:t:")) > 0 )
	{
		switch(opt)
		{
			/* [addr:]port */
			case 'p':
			case 's':
				if( (port = strrchr(optarg, ':')) != NULL )
				{
					if( (optarg[0] == '[') && (port > optarg) && (port[-1] == ']') )
						memcpy(bind, optarg + 1,
							min(sizeof(bind), (int)(port - optarg) - 2));
					else
						memcpy(bind, optarg,
							min(sizeof(bind), (int)(port - optarg)));

					port++;
				}
				else
				{
					port = optarg;
				}

#ifdef HAVE_TLS
				if( opt == 's' )
				{
					if( !conf.tls )
					{
						fprintf(stderr,
							"Notice: TLS support is disabled, "
							"ignoring '-s %s'\n", optarg
						);
						continue;
					}

					tls = 1;
				}
#endif

				/* bind sockets */
				bound += uh_socket_bind(
					&serv_fds, &max_fd, bind[0] ? bind : NULL, port,
					&hints,	(opt == 's'), &conf
				);

				break;

#ifdef HAVE_TLS
			/* certificate */
			case 'C':
				if( conf.tls )
				{
					if( conf.tls_cert(conf.tls, optarg) < 1 )
					{
						fprintf(stderr,
							"Error: Invalid certificate file given\n");
						exit(1);
					}

					keys++;
				}

				break;

			/* key */
			case 'K':
				if( conf.tls )
				{
					if( conf.tls_key(conf.tls, optarg) < 1 )
					{
						fprintf(stderr,
							"Error: Invalid private key file given\n");
						exit(1);
					}

					keys++;
				}

				break;
#endif

			/* docroot */
			case 'h':
				if( ! realpath(optarg, conf.docroot) )
				{
					fprintf(stderr, "Error: Invalid directory %s: %s\n",
						optarg, strerror(errno));
					exit(1);
				}
				break;

#ifdef HAVE_CGI
			/* cgi prefix */
			case 'x':
				conf.cgi_prefix = optarg;
				break;
#endif

#ifdef HAVE_LUA
			/* lua prefix */
			case 'l':
				conf.lua_prefix = optarg;
				break;

			/* lua handler */
			case 'L':
				conf.lua_handler = optarg;
				break;
#endif

#if defined(HAVE_CGI) || defined(HAVE_LUA)
			/* script timeout */
			case 't':
				conf.script_timeout = atoi(optarg);
				break;
#endif

			/* no fork */
			case 'f':
				nofork = 1;
				break;

			/* urldecode */
			case 'd':
				if( (port = malloc(strlen(optarg)+1)) != NULL )
				{
					memset(port, 0, strlen(optarg)+1);
					uh_urldecode(port, strlen(optarg), optarg, strlen(optarg));
					printf("%s", port);
					free(port);
					exit(0);
				}
				break;

			/* basic auth realm */
			case 'r':
				conf.realm = optarg;
				break;

			/* md5 crypt */
			case 'm':
				printf("%s\n", crypt(optarg, "$1$"));
				exit(0);
				break;

			/* config file */
			case 'c':
				conf.file = optarg;
				break;

			default:
				fprintf(stderr,
					"Usage: %s -p [addr:]port [-h docroot]\n"
					"	-f              Do not fork to background\n"
					"	-c file         Configuration file, default is '/etc/httpd.conf'\n"
					"	-p [addr:]port  Bind to specified address and port, multiple allowed\n"
#ifdef HAVE_TLS
					"	-s [addr:]port  Like -p but provide HTTPS on this port\n"
					"	-C file         ASN.1 server certificate file\n"
					"	-K file         ASN.1 server private key file\n"
#endif
					"	-h directory    Specify the document root, default is '.'\n"
#ifdef HAVE_LUA
					"	-l string       URL prefix for Lua handler, default is '/lua'\n"
					"	-L file         Lua handler script, omit to disable Lua\n"
#endif
#ifdef HAVE_CGI
					"	-x string       URL prefix for CGI handler, default is '/cgi-bin'\n"
#endif
#if defined(HAVE_CGI) || defined(HAVE_LUA)
					"	-t seconds      CGI and Lua script timeout in seconds, default is 60\n"
#endif
					"	-d string       URL decode given string\n"
					"	-r string       Specify basic auth realm\n"
					"	-m string       MD5 crypt given string\n"
					"\n", argv[0]
				);

				exit(1);
		}
	}

#ifdef HAVE_TLS
	if( (tls == 1) && (keys < 2) )
	{
		fprintf(stderr, "Error: Missing private key or certificate file\n");
		exit(1);
	}
#endif

	if( bound < 1 )
	{
		fprintf(stderr, "Error: No sockets bound, unable to continue\n");
		exit(1);
	}

	/* default docroot */
	if( !conf.docroot[0] && !realpath(".", conf.docroot) )
	{
		fprintf(stderr, "Error: Can not determine default document root: %s\n",
			strerror(errno));
		exit(1);
	}

	/* default realm */
	if( ! conf.realm )
		conf.realm = "Protected Area";

	/* config file */
	uh_config_parse(conf.file);

#if defined(HAVE_CGI) || defined(HAVE_LUA)
	/* default script timeout */
	if( conf.script_timeout <= 0 )
		conf.script_timeout = 60;
#endif

#ifdef HAVE_CGI
	/* default cgi prefix */
	if( ! conf.cgi_prefix )
		conf.cgi_prefix = "/cgi-bin";
#endif

#ifdef HAVE_LUA
	/* load Lua plugin */
	if( ! (lua_lib = dlopen("uhttpd_lua.so", RTLD_LAZY | RTLD_GLOBAL)) )
	{
		fprintf(stderr,
			"Notice: Unable to load Lua plugin - disabling Lua support! "
			"(Reason: %s)\n", dlerror()
		);
	}
	else
	{
		/* resolve functions */
		if( !(conf.lua_init    = dlsym(lua_lib, "uh_lua_init"))    ||
		    !(conf.lua_close   = dlsym(lua_lib, "uh_lua_close"))   ||
		    !(conf.lua_request = dlsym(lua_lib, "uh_lua_request"))
		) {
			fprintf(stderr,
				"Error: Failed to lookup required symbols "
				"in Lua plugin: %s\n", dlerror()
			);
			exit(1);
		}

		/* init Lua runtime if handler is specified */
		if( conf.lua_handler )
		{
			/* default lua prefix */
			if( ! conf.lua_prefix )
				conf.lua_prefix = "/lua";

			L = conf.lua_init(conf.lua_handler);
		}
	}
#endif

	/* fork (if not disabled) */
	if( ! nofork )
	{
		switch( fork() )
		{
			case -1:
				perror("fork()");
				exit(1);

			case 0:
				/* daemon setup */
				if( chdir("/") )
					perror("chdir()");

				if( (cur_fd = open("/dev/null", O_WRONLY)) > -1 )
					dup2(cur_fd, 0);

				if( (cur_fd = open("/dev/null", O_RDONLY)) > -1 )
					dup2(cur_fd, 1);

				if( (cur_fd = open("/dev/null", O_RDONLY)) > -1 )
					dup2(cur_fd, 2);

				break;

			default:
				exit(0);
		}
	}

	/* backup server descriptor set */
	used_fds = serv_fds;

	/* loop */
	while(run)
	{
		/* create a working copy of the used fd set */
		read_fds = used_fds;

		/* sleep until socket activity */
		if( select(max_fd + 1, &read_fds, NULL, NULL, NULL) == -1 )
		{
			perror("select()");
			exit(1);
		}

		/* run through the existing connections looking for data to be read */
		for( cur_fd = 0; cur_fd <= max_fd; cur_fd++ )
		{
			/* is a socket managed by us */
			if( FD_ISSET(cur_fd, &read_fds) )
			{
				/* is one of our listen sockets */
				if( FD_ISSET(cur_fd, &serv_fds) )
				{
					/* handle new connections */
					if( (new_fd = accept(cur_fd, NULL, 0)) != -1 )
					{
						/* add to global client list */
						if( (cl = uh_client_add(new_fd, uh_listener_lookup(cur_fd))) != NULL )
						{
#ifdef HAVE_TLS
							/* setup client tls context */
							if( conf.tls )
								conf.tls_accept(cl);
#endif

							/* add client socket to global fdset */
							FD_SET(new_fd, &used_fds);
							fd_cloexec(new_fd);
							max_fd = max(max_fd, new_fd);
						}

						/* insufficient resources */
						else
						{
							fprintf(stderr,
								"uh_client_add(): Can not manage more than "
								"%i client sockets, connection dropped\n",
								UH_LIMIT_CLIENTS
							);

							close(new_fd);
						}
					}
				}

				/* is a client socket */
				else
				{
					if( ! (cl = uh_client_lookup(cur_fd)) )
					{
						/* this should not happen! */
						fprintf(stderr,
							"uh_client_lookup(): No entry for fd %i!\n",
							cur_fd);

						goto cleanup;
					}

					/* parse message header */
					if( (req = uh_http_header_recv(cl)) != NULL )
					{
#ifdef HAVE_LUA
						/* Lua request? */
						if( L && uh_path_match(conf.lua_prefix, req->url) )
						{
							conf.lua_request(cl, req, L);
						}
						else
#endif
						/* dispatch request */
						if( (pin = uh_path_lookup(cl, req->url)) != NULL )
						{
							/* auth ok? */
							if( uh_auth_check(cl, req, pin) )
							{
#ifdef HAVE_CGI
								if( uh_path_match(conf.cgi_prefix, pin->name) )
								{
									uh_cgi_request(cl, req, pin);
								}
								else
#endif
								{
									uh_file_request(cl, req, pin);
								}
							}
						}

						/* 404 */
						else
						{
							uh_http_sendhf(cl, 404, "Not Found",
								"No such file or directory");
						}
					}

					/* 400 */
					else
					{
						uh_http_sendhf(cl, 400, "Bad Request",
							"Malformed request received");
					}

#ifdef HAVE_TLS
					/* free client tls context */
					if( conf.tls )
						conf.tls_close(cl);
#endif

					cleanup:

					/* close client socket */
					close(cur_fd);
					FD_CLR(cur_fd, &used_fds);

					/* remove from global client list */
					uh_client_remove(cur_fd);
				}
			}
		}
	}

#ifdef HAVE_LUA
	/* destroy the Lua state */
	if( L != NULL )
		conf.lua_close(L);
#endif

	return 0;
}
void main( int argc,  char*  argv[] )
{
   int i, ready, sock1, sock2, length; 
   /* This receiver process will receive connection requests on these two sockets */ 
   int msgsock ; 

   fd_set fdin;
   struct timeval TO ; 

   struct sockaddr_in server, server2;  

   /* CREATE FIRST SOCKET 				   			*/
   sock1  = socket(AF_INET, SOCK_STREAM,0); 

   if ( sock1 < 0 ) { 
      perror("Problem in creating the first socket");
       exit(0); 
    } 

   server.sin_addr.s_addr = INADDR_ANY ; 
   server.sin_port = 0 ; 
   if ( bind(sock1,(struct sockaddr *)&server, sizeof(server))) {   /* Bind socket to a port */ 
      perror ( "Binding stream socket");
      exit(0);
   }

   length = sizeof(server); 
   if ( getsockname(sock1,(struct sockaddr *)&server, &length)) {  /* get the port number assigned to this socket */ 
        perror("Getting socket's port number");
        exit(0);
   }

   fprintf(stderr, "Socket 1 is connected to port%5d\n\n", ntohs(server.sin_port)); 

   /* CREATE SECOND SOCKET 				 			*/
   sock2 = socket(AF_INET, SOCK_STREAM, 0);
 
   if ( sock2 < 0 ) {
      perror("problem in creating the second  socket");
      exit(0);
   } 

   server2.sin_addr.s_addr = INADDR_ANY; 
   server2.sin_port = 0 ; 
   if ( bind(sock2, (struct sockaddr * )&server2,sizeof(server2))){ /* bind second socket to a port */
        perror("Binding stream socket");
        exit(0);
   }

   length = sizeof(server2);
   if ( getsockname(sock2,(struct sockaddr *)&server2,&length)){  /* get the port number for socket2 */
      perror("getting socket's port number");
      exit(0);
    }

    fprintf(stderr,"Socket 2  is connected to port %5d\n", ntohs(server2.sin_port));

    /* Initialize socket fo receiving messages.						*/
    /*  ready to accept connection to sock1, up to 3 requests can be kept buffered */
    listen(sock1,3);     
    listen(sock2,3);     

    /* Continuously wait for receiving messages on either of the two sockets.		*/
    while (1) { 
        FD_ZERO( &fdin );
        FD_SET( sock1, &fdin);
        FD_SET( sock2, &fdin);
        TO.tv_sec = 10 ; 
        TO.tv_usec = 0 ; 
  
        select(32, (fd_set *)&fdin, 0, 0, &TO);  /* Block to receive call on either sock1 or sock2 */
                       /* timeout and continue after 10 seconds if no connection requests */

        if (FD_ISSET(sock1, &fdin )) {   /* check if connection requests for sock1  */ 
             printf("\nMessage on the first socket\n");

             /* accept connection on sock1. This will return a new socket indentifier, stored 
             in msgsock for the connection. All I/O for that connection is through msgsock.  */
              handle_connection(sock1);
              FD_CLR(sock1, &fdin);
         }
         else if (FD_ISSET(sock2, &fdin)) {    /* check if connection requests for sock2  */
              printf("\nMessage on the second socket\n");
              /* accept connection on sock2. This will return a new socket indentifier, stored 
              in msgsock for the connection. All I/O for that connection is through msgsock.  */

              handle_connection(sock2);
              FD_CLR(sock2,  &fdin);
             } 
            else  /* Select call completed due to timeout and there is no connection on any socket */
                  printf("\nTimeout occured\n"); 
      };

}  
/**
 * DTLS over SCTP specific listener function. This function is called by @c listenerThread()
 */
void IpfixReceiverDtlsSctpIpV4::run() {

    struct sockaddr_in clientAddress;
    socklen_t clientAddressLen = sizeof(struct sockaddr_in);

    int ret;
    int rfd;
    struct timespec timeOut;

    /* set a 400ms time-out on the pselect */
    timeOut.tv_sec = 0L;
    timeOut.tv_nsec = 400000000L;

    while(!exitFlag) {
	fd_set tmpreadfds = readfds;
	fd_set tmpwritefds = writefds;
	ret = pselect(maxfd + 1, &tmpreadfds, &tmpwritefds, NULL, &timeOut, NULL);
	if (ret == 0) {
	    /* Timeout */
	    continue;
	}
	if ((ret == -1) && (errno == EINTR)) {
	    DPRINTF("select() returned due to signal");
	    /* There was a signal... ignore */
	    continue;
	}
	if (ret < 0) {
	    msg(MSG_ERROR ,"select() returned with an error: %s",strerror(errno));
	    THROWEXCEPTION("IpfixReceiverDtlsSctpIpV4: terminating listener thread");
	    break;
	}
	DPRINTF("select() returned %d",ret);
	// looking for a new client to connect at listen_socket
	if (FD_ISSET(listen_socket, &tmpreadfds)){
	    rfd = accept(listen_socket, (struct sockaddr*)&clientAddress, &clientAddressLen);

	    if (rfd >= 0){
		if ( ! isHostAuthorized(&clientAddress.sin_addr,
			    sizeof(clientAddress.sin_addr))) {
		    /* Do not accept connections from unauthorized hosts. */
		    close(rfd);
		} else {
		    msg(MSG_DEBUG, "IpfixReceiverDtlsSctpIpV4: Client connected from %s:%d, FD=%d", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port), rfd);
		    DtlsConnectionPtr conn = DtlsConnectionPtr( new DtlsConnection(*this,&clientAddress,rfd));
		    connections.insert(make_pair(rfd,conn));
		    update_maxfd();
		}
	    }else{
		msg(MSG_ERROR ,"accept() in ipfixReceiver failed");
		/* TODO: Don't throw an exception here. */
		THROWEXCEPTION("IpfixReceiverDtlsSctpIpV4: unable to accept new connection");
	    }
	}
	// check all connected sockets for new available data
	for (rfd = 0; rfd <= maxfd; ++rfd) {
	    if (rfd == listen_socket) continue;
	    if (FD_ISSET(rfd, &readfds) || FD_ISSET(rfd, &writefds)) {
		if (FD_ISSET(rfd, &readfds)) DPRINTF("descriptor %d is ready for reading",rfd);
		if (FD_ISSET(rfd, &writefds)) DPRINTF("descriptor %d is ready for writing",rfd);
		connections_map::iterator it = connections.find(rfd);
		if (it == connections.end()) {
		    /* This should not happend. */
		    msg(MSG_ERROR,"Can't find connection for file descriptor.");
		    FD_CLR(rfd,&readfds);
		    FD_CLR(rfd,&writefds);
		    continue;
		}
		ret = it->second->fdready();
		if (ret == 0) {
		    DPRINTF("fdready() returned 0. Deleting connection.");
		    remove_connection(rfd);
		    update_maxfd();
		}
	    }
	}
    }
    msg(MSG_DEBUG, "IpfixReceiverDtlsSctpIpV4: Exiting");
}
Example #27
0
int main(int argc, char const *argv[])
{
	int listendfd, connfd;
	int maxfd;
	int clilent[FD_SETSIZE];
	fd_set rset, allset;
	pid_t childid;
	socklen_t clilen;
	struct sockaddr_in servaddr, cliaddr;
	char buff[MAXLINE + 1] = {0};
	time_t ticks;

	listendfd = Socket(AF_INET, SOCK_STREAM,0);

	bzero(&servaddr, sizeof(servaddr));

	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(PORT);
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	bind(listendfd, (struct sockaddr*)&servaddr, sizeof(servaddr));

	listen(listendfd, LISTENQ);

	signal(SIGCHLD, sig_chld);

	maxfd = listendfd;
	for(;;)
	{
		rset = allset;
		nready = select(maxfd + 1, &rset, NULL,NULL,NULL);
		if(FD_ISSET(listendfd))
		{
			clilen = sizeof(cliaddr);
			connfd = accept(listendfd, (struct sockaddr*)&cliaddr,&clilen);
			if(connfd < 0)
			{
				if(errno == EINTR)
				{
					continue;
				}
				else
				{
					perror("accept");
				}
			}

			for(i = 0; i< FD_SETSIZE; ++i)
			{
				if(clilent[i] < 0)
					clilent[i] = connfd;
				break;
			}

			if(i == FD_SETSIZE)
			{
				printf("too many clients\n");
			}

			FD_SET(connfd, &allset);

			if(connfd > maxfd)
				maxfd = connfd;

			if(i > maxi)
				maxi = i;

			if(--nready < 0)
				continue;

		}

		for(i = 0; i < maxfd; ++i)
		{
			if( (sockfd = clilent[i]) < 0)
				continue;
			if(FD_ISSET(sockfd, &rset))
			{
				if( (n = read(sockfd, buff, MAXLINE)) == 0)
				{
					close(sockfd);
					FD_CLR(sockfd, &allset);
					clilent[i] = -1;
				}
				else
				{
					write(sockfd, buff, n);
				}

				if(--nready <= 0)
				{
					break;
				}
			}
		}
	}

	return 0;
}
Example #28
0
int main(int argc,char **argv) {
    int i,srv_sock,j,retval,ptype;
    struct sockaddr_in srv_sa;
    int clientfds[MAX_CLIENTS];
    char *clientsas[MAX_CLIENTS];
    int client_cnt = 0;
    int block_size = 1024;
    int maxfd = 0;
    int c;
    char *srvhost = NULL;
    short srvport = DEF_SRV_PORT;
    int proto = DEF_PROTO;
    int debug = 0;
    char *buf = NULL;
    fd_set rfds;
    fd_set static_rfds;

    /* grab some quick args, hostname, port, tcp, udp... */
    while ((c = getopt(argc,argv,"h:p:tudb:")) != -1) {
	switch(c) {
	case 'h':
	    srvhost = optarg;
	    break;
	case 'p':
	    srvport = atoi(optarg);
	    break;
	case 't':
	    proto = SOCK_STREAM;
	    break;
	case 'u':
	    proto = SOCK_DGRAM;
	    fatal("no udp support yet!");
	    break;
	case 'd':
	    ++debug;
	    break;
	case 'b':
	    block_size = atoi(optarg);
	    break;
	default:
	    break;
	}
    }

    if ((buf = (char *)malloc(sizeof(char)*block_size)) == NULL) {
	efatal("no memory for data buf");
    }
    
    if ((retval = fill_sockaddr(srvhost,srvport,&srv_sa)) != 0) {
	if (retval == -1) {
	    fatal("bad port");
	}
	else {
	    efatal("host lookup failed");
	}
    }

    /* startup server... */
    if ((srv_sock = socket(AF_INET,proto,0)) == -1) {
	efatal("could not get socket");
    }

    if (bind(srv_sock,
	     (struct sockaddr *)&srv_sa,
	     sizeof(struct sockaddr_in)
	     ) < 0) {
	efatal("could not bind");
    }

    if (proto == PROTO_TCP) {
	if (listen(srv_sock,8) < 0) {
	    efatal("could not listen");
	}
    }

    /* daemonize... */
    if (!debug) {
	daemon(0,0);
    }

    for (i = 0; i < MAX_CLIENTS; ++i) {
	clientfds[i] = -1;
	clientsas[i] = (char *)malloc(MAX_NAME_LEN + 1);
    }

    FD_ZERO(&static_rfds);
    FD_SET(srv_sock,&static_rfds);
    maxfd = srv_sock;
    
    /* listen and read forever */
    while (1) {
	/* reset fdsets */
	memcpy(&rfds,&static_rfds,sizeof(static_rfds));

	retval = select(maxfd+1,&rfds,NULL,NULL,NULL);
	
	if (retval > 0) {
	    if (FD_ISSET(srv_sock,&rfds)) {
		struct sockaddr_in client_sin;
		socklen_t slen;
		int client_fd;

		slen = sizeof(client_sin);

		if ((client_fd = accept(srv_sock,
					(struct sockaddr *)&client_sin,
					&slen)) < 0) {
		    warn("accept failed");
		}
		else if (client_cnt >= MAX_CLIENTS) {
		    warn("already at max clients");
		}
		else {
		    /* add new client... */
		    for (i = 0; i < MAX_CLIENTS; ++i) {
			if (clientfds[i] == -1) {
			    break;
			}
		    }
		    
		    clientfds[i] = client_fd;
		    if (client_fd > maxfd) {
			maxfd = client_fd;
		    }
		    
		    FD_SET(client_fd,&static_rfds);
		    
		    if (debug) {
			fprintf(stdout,
				"connect from %s:%d\n",
				inet_ntoa(client_sin.sin_addr),
				ntohs(client_sin.sin_port));
		    }
		    
		    char *addr = inet_ntoa(client_sin.sin_addr);
		    int addrlen = strlen(addr);
		    
		    strncpy(clientsas[i],
			    addr,
			    (addrlen > MAX_NAME_LEN)?MAX_NAME_LEN:addrlen);
		    /* null term if strncpy couldn't */
		    if (addrlen > MAX_NAME_LEN) {
			clientsas[i][MAX_NAME_LEN] = '\0';
		    }
		    
		    ++client_cnt;
		}
	    }
	    else {
		for (i = 0; i < MAX_CLIENTS; ++i) {
		    if (clientfds[i] > -1) {
			if (FD_ISSET(clientfds[i],&rfds)) {
			    /* read a block, or as much as possible */
			    retval = read(clientfds[i],buf,block_size);

			    /* dead client, pretty much */
			    if (retval <= 0) {
				if (debug) {
				    fprintf(stdout,
					    "disconnect from %s\n",
					    clientsas[i]);
				}

				close(clientfds[i]);
				FD_CLR(clientfds[i],&static_rfds);
				clientfds[i] = -1;

				--client_cnt;
			    }
			    else if (debug > 2 ) {
				fprintf(stdout,
					"DEBUG: read %d bytes from %s\n",
					retval,
					clientsas[i]);
			    }
			}
		    }
		}
	    }
	}
	else if (retval < 0) {
	    /* error... */
	    ewarn("error in select");
	}
    }

    return -1;
}
Example #29
0
void relay_udp(SOCKS_STATE *state)
{
  fd_set   rfds;
  int      nfds, sfd;
  struct   timeval tv;
  struct   timezone tz;
  ssize_t  wc;
  rlyinfo  ri;
  int      done;
  u_long   max_count = idle_timeout;
  u_long   timeout_count;
  struct sockaddr_storage ss;
  LOGINFO	li;

  memset(&ri, 0, sizeof(ri));
  memset(&li, 0, sizeof(li));
  ri.ss = (struct sockaddr *)&ss;
  ri.flags = 0;
  ri.nr = BUFSIZE-sizeof(UDPH);

  setsignal(SIGALRM, timeout);
  gettimeofday(&li.start, &tz);
  li.bc = li.upl = li.dnl = 0;
  timeout_count = 0;
  for (;;) {
    FD_ZERO(&rfds);
    FD_SET(state->s, &rfds); FD_SET(state->sr.udp->d, &rfds);
    nfds = MAX(state->s, state->sr.udp->d);
    if (state->r >= 0) {
      FD_SET(state->r, &rfds);
      nfds = MAX(nfds, state->r);
    }
    if (state->sr.udp->u >= 0) {
      FD_SET(state->sr.udp->u, &rfds);
      nfds = MAX(nfds, state->sr.udp->u);
    }

    done = 0;
    /* idle timeout related setting. */
    tv.tv_sec = 60; tv.tv_usec = 0;   /* unit = 1 minute. */
    tz.tz_minuteswest = 0; tz.tz_dsttime = 0;
    sfd = select(nfds+1, &rfds, 0, 0, &tv);
    if (sfd > 0) {
      /* UDP channels */
      /* in case of UDP, wc == 0 does not mean EOF (??) */
      if (FD_ISSET(state->sr.udp->d, &rfds)) {
	ri.from = state->sr.udp->d; ri.to = state->sr.udp->u;
	ri.dir = UP;
	if ((wc = forward_udp(&ri, state->sr.udp, state->rtbl.rl_meth)) < 0)
	  done++;
	else
	  li.bc += wc; li.upl += wc;
	FD_CLR(state->sr.udp->d, &rfds);
      }
      if (state->sr.udp->u >= 0 && FD_ISSET(state->sr.udp->u, &rfds)) {
	ri.from = state->sr.udp->u; ri.to = state->sr.udp->d;
	ri.dir = DOWN;
	if ((wc = forward_udp(&ri, state->sr.udp, state->rtbl.rl_meth)) < 0)
	  done++;
	else
	  li.bc += wc; li.dnl += wc;
	FD_CLR(state->sr.udp->d, &rfds);
      }
      /* packets on TCP channel may indicate
	 termination of UDP assoc.
      */
      if (FD_ISSET(state->s, &rfds)) {
	ri.from = state->s; ri.to = state->r; ri.flags = 0;
	if ((wc = forward(&ri)) <= 0)
	  done++;
	FD_CLR(state->s, &rfds);
      }
      if (FD_ISSET(state->r >= 0 && state->r, &rfds)) {
	ri.from = state->r; ri.to = state->s; ri.flags = 0;
	if ((wc = forward(&ri)) <= 0)
	  done++;
	FD_CLR(state->r, &rfds);
      }
      if (done > 0)
	break;
    } else if (sfd < 0) {
      if (errno != EINTR)
	break;
    } else { /* sfd == 0 */
      if (max_count != 0) {
	timeout_count++;
	if (timeout_count > max_count)
	  break;
      }
    }
  }

  gettimeofday(&li.end, &tz);
  /* getsockname for logging */
  state->sr.udp->si.myc.len = SS_LEN;
  getsockname(state->sr.udp->d,
	      &state->sr.udp->si.myc.addr.sa,
	      (socklen_t *)&state->sr.udp->si.myc.len);
  if (state->sr.udp->u >= 0) {
    state->sr.udp->si.mys.len = SS_LEN;
    getsockname(state->sr.udp->u,
		&state->sr.udp->si.mys.addr.sa,
		(socklen_t *)&state->sr.udp->si.mys.len);
  }

  log_transfer(&state->sr.udp->si, &li);

  close(state->s);
  if (state->r >= 0)
    close(state->r);
  close(state->sr.udp->d);
  if (state->sr.udp->u >= 0)
    close(state->sr.udp->u);
  if (state->sr.udp != NULL)
    free(state->sr.udp);
}
Example #30
0
void net_unregister_except(int fd)
{
  FD_CLR(fd, &global_except_set);
}