Example #1
0
int Ctcs::Connect()
{
  ssize_t r;
  m_last_timestamp = now;

  if( _s2sin(m_host, m_port, &m_sin) < 0 ){
    CONSOLE.Warning(2, "warn, get CTCS ip address failed.");
    return -1;
  }

  m_sock = socket(AF_INET, SOCK_STREAM, 0);
  if( INVALID_SOCKET == m_sock ) return -1;

  if( setfd_nonblock(m_sock) < 0 ){
    CLOSE_SOCKET(m_sock);
    m_sock = INVALID_SOCKET;
    return -1;
  }

  r = connect_nonb(m_sock, (struct sockaddr *)&m_sin);
  if( r == -1 ){
    CLOSE_SOCKET(m_sock);
    m_sock = INVALID_SOCKET;
    return -1;
  }else if( r == -2 ){
    m_status = DT_TRACKER_CONNECTING;
  }else{
    m_status = DT_TRACKER_READY;
    if(*cfg_verbose) CONSOLE.Debug("Connected to CTCS");
    if( Send_Protocol() != 0 && errno != EINPROGRESS ){
      CONSOLE.Warning(2, "warn, send protocol to CTCS failed:  %s",
        strerror(errno));
      return -1;
    }
    if( Send_Auth() != 0 && errno != EINPROGRESS ){
      CONSOLE.Warning(2, "warn, send password to CTCS failed:  %s",
        strerror(errno));
      return -1;
    }
    if( Send_Torrent(BTCONTENT.GetPeerId(), BTCONTENT.GetMetainfoFile()) < 0 &&
        errno != EINPROGRESS ){
      CONSOLE.Warning(2, "warn, send torrent to CTCS failed:  %s",
        strerror(errno));
      return -1;
    }
  }
  return 0;
}
Example #2
0
int btTracker::Connect()
{
	ssize_t r;
	time(&m_last_timestamp);

	if (_s2sin(m_host, m_port, &m_sin) < 0) {
		CONSOLE.Warning(2, "warn, get tracker's ip address failed.");
		return -1;
	}

	m_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (INVALID_SOCKET == m_sock)
		return -1;

	// we only need to bind if we have specified an ip
	// we need it to bind here before the connect!!!!
	if (cfg_listen_ip != 0) {
		struct sockaddr_in addr;
		// clear the struct as requested in the manpages
		memset(&addr, 0, sizeof(sockaddr_in));
		// set the type
		addr.sin_family = AF_INET;
		// we want the system to choose port
		addr.sin_port = 0;
		// set the defined ip from the commandline
		addr.sin_addr.s_addr = cfg_listen_ip;
		// bind it or return...
		if (bind
			(m_sock, (struct sockaddr *) &addr,
			sizeof(struct sockaddr_in)) != 0) {
			CONSOLE.Warning(1,
				"warn, can't set up tracker connection:  %s",
				strerror(errno));
			return -1;
		}
	}

	if (setfd_nonblock(m_sock) < 0) {
		CLOSE_SOCKET(m_sock);
		return -1;
	}

	r = connect_nonb(m_sock, (struct sockaddr *) &m_sin);

	if (r == -1) {
		CLOSE_SOCKET(m_sock);
		return -1;
	} else if (r == -2)
		m_status = T_CONNECTING;
	else {
		if (arg_verbose)
			CONSOLE.Debug("Connected to tracker");
		if (0 == SendRequest())
			m_status = T_READY;
		else {
			CLOSE_SOCKET(m_sock);
			return -1;
		}
	}
	return 0;
}
Example #3
0
int su_serv_create(su_serv_t *psvr, const SA *saddr, socklen_t servlen, int nthread)
{
    if (nthread <= 0) {
        errno = EINVAL;
        return -1;
    }
    psvr->fd = socket(saddr->sa_family, SOCK_DGRAM, 0);
    if (psvr->fd < 0) {
        err_ret("serv %x create failed, socket error", psvr);
        return -1;
    }
    if (bind(psvr->fd, saddr, servlen) < 0) {
        close(psvr->fd);
        psvr->fd = -1;
        return -1;
    }
    if (setfd_nonblock(psvr->fd) < 0) {
        close(psvr->fd);
        psvr->fd = -1;
        return -1;
    }

    memset(&psvr->servaddr, 0, sizeof(SAUN));
    memcpy(&psvr->servaddr, saddr, servlen);
    psvr->servlen = servlen;

    psvr->seq = 0;
    psvr->rttinit = 0;
    psvr->retry = RTT_MAXNREXMT;

    psvr->ackwaitnum = 0;
    list_init(&psvr->ackrecvls);
    list_init(&psvr->synrecvls);
    list_init(&psvr->lsackcache);
    rbt_init(&psvr->rbackcache, cache_getkey, search_cache_cmp);

    pthread_mutex_init(&psvr->mutex, 0);
    pthread_mutex_init(&psvr->lock, 0);
    pthread_cond_init(&psvr->ackcond, 0);
    pthread_cond_init(&psvr->syncond, 0);
    pthread_mutex_init(&psvr->cachelock, 0);

    if (su_serv_thread_install(psvr, nthread) < 0) {
        pthread_mutex_destroy(&psvr->mutex);
        pthread_mutex_destroy(&psvr->lock);
        pthread_mutex_destroy(&psvr->cachelock);
        pthread_cond_destroy(&psvr->ackcond);
        pthread_cond_destroy(&psvr->syncond);
        close(psvr->fd);
        psvr->fd = -1;
        return -1;
    }

    pthread_mutex_lock(&emutex);
    if (sugem == 0) {
        sugem = Em_open(100, -1, 0, 0, 0);
        Em_run(sugem);

        struct timeval now;
        gettimeofday(&now, 0);
        srand(now.tv_sec % 1000 + now.tv_usec);
    }
    psvr->sid = rand() % 65535;
    pthread_mutex_unlock(&emutex);

    memset(&psvr->fe, 0, sizeof(fe_t));
    fe_init(&psvr->fe, sugem, psvr->fd);
    fe_set(&psvr->fe, EPOLLIN, handle_su_serv_recv);
    fe_set(&psvr->fe, EPOLLET, 0);
    Fe_em_add(&psvr->fe);

    return psvr->fd;
}
Example #4
0
int su_peer_create_bind(su_peer_t *psar, int port, const SA *destaddr, socklen_t destlen)
{
    psar->fd = socket(destaddr->sa_family, SOCK_DGRAM, 0);
    if (psar->fd < 0) {
        err_ret("peer %x create failed, socket error", psar);
        return -1;
    }

    if (port > 0 && port <= 65535) {
        void *paddr;
        SA4 s4;
        SA6 s6;
        switch (destaddr->sa_family) {
            case PF_INET:
                memcpy(&s4, destaddr, destlen);  /* for sin_family and more... */
                s4.sin_port = htons(port);
                inet_pton(PF_INET, "0.0.0.0", &s4.sin_addr.s_addr);
                paddr = &s4;
                break;
            case PF_INET6:
                memcpy(&s6, destaddr, destlen); /* for sin6_family and more...  */
                s6.sin6_port = htons(port);
                inet_pton(PF_INET6, "::", &s6.sin6_addr.__in6_u);
                paddr = &s6;
                break;
            default:
                close(psar->fd);
                psar->fd = -1;
                errno = EINVAL;
                return -1;
        }
        int reuse = 1;
        if (setsockopt(psar->fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0) {
            close(psar->fd);
            psar->fd = -1;
            return -1;
        }
        if (bind(psar->fd, paddr, destlen) < 0) {
            close(psar->fd);
            psar->fd = -1;
            return -1;
        }
    }

    if (setfd_nonblock(psar->fd) < 0) {
        close(psar->fd);
        psar->fd = -1;
        return -1;
    }

    memset(&psar->destaddr, 0, sizeof(SAUN));
    memcpy(&psar->destaddr, destaddr, destlen);
    psar->destlen = destlen;

    psar->seq = 0;
    psar->rttinit = 0;
    psar->retry = RTT_MAXNREXMT;

    psar->ackwaitnum = 0;
    list_init(&psar->ackrecvls);
    list_init(&psar->synrecvls);
    list_init(&psar->lsackcache);
    rbt_init(&psar->rbackcache, cache_getkey, search_cache_cmp);

    psar->nowsynframe = 0;

    pthread_mutex_init(&psar->mutex, 0);
    pthread_mutex_init(&psar->lock, 0);
    pthread_cond_init(&psar->ackcond, 0);
    pthread_cond_init(&psar->syncond, 0);
    pthread_mutex_init(&psar->cachelock, 0);

    if (su_peer_thread_install(psar) < 0) {
        pthread_mutex_destroy(&psar->mutex);
        pthread_mutex_destroy(&psar->lock);
        pthread_cond_destroy(&psar->ackcond);
        pthread_cond_destroy(&psar->syncond);
        pthread_mutex_destroy(&psar->cachelock);

        close(psar->fd);
        psar->fd = -1;
        return -1;
    }

    pthread_mutex_lock(&emutex);
    if (sugem == 0) {
        sugem = Em_open(100, -1, 0, 0, 0);
        Em_run(sugem, 1);

        struct timeval now;
        gettimeofday(&now, 0);
        srand(now.tv_sec % 1000 + now.tv_usec);
    }
    psar->sid = rand() % 65535;
    pthread_mutex_unlock(&emutex);

    memset(&psar->fe, 0, sizeof(fe_t));
    fe_init(&psar->fe, sugem, psar->fd);
    fe_set(&psar->fe, EPOLLIN, handle_su_peer_recv);
    fe_set(&psar->fe, EPOLLET, 0);
    Fe_em_add(&psar->fe);

    return psar->fd;
}
Example #5
0
int btTracker::Connect()
{
  struct sockaddr_in sin;
  ssize_t r;

  m_result = DT_NORMAL;
  m_last_timestamp = now;

  if( _s2sin(m_spec->host, m_spec->port, &sin) < 0 ){
    CONSOLE.Warning(2, "warn, get tracker's ip address failed.");
    return -1;
  }

  m_sock = socket(AF_INET, SOCK_STREAM, 0);
  if( INVALID_SOCKET == m_sock ){
    CONSOLE.Warning(2, "warn, tracker socket allocation failed:  %s",
      strerror(errno));
    return -1;
  }

  /* we only need to bind if we have specified an ip
     we need it to bind here before the connect! */
  if( *cfg_listen_ip != 0 ){
    struct sockaddr_in addr;
    // clear the struct as requested in the manpages
    memset(&addr, 0, sizeof(sockaddr_in));
    // set the type
    addr.sin_family = AF_INET;
    // we want the system to choose port
    addr.sin_port = 0;
    // set the defined ip from the commandline
    addr.sin_addr.s_addr = *cfg_listen_ip;
    // bind it or return...
    if( bind(m_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))
          != 0 ){
      CONSOLE.Warning(1, "warn, can't set up tracker connection:  %s",
        strerror(errno));
      return -1;
    }
  }

  if( setfd_nonblock(m_sock) < 0 ){
    CONSOLE.Warning(2, "warn, tracker socket setup failed:  %s",
      strerror(errno));
    CLOSE_SOCKET(m_sock);
    m_sock = INVALID_SOCKET;
    return -1;
  }

  r = connect_nonb(m_sock, (struct sockaddr *)&sin);
  if( r == -1 ){
    CONSOLE.Warning(2, "warn, connect to tracker at %s failed:  %s",
      m_spec->url, strerror(errno));
    CLOSE_SOCKET(m_sock);
    m_sock = INVALID_SOCKET;
    return -1;
  }else if( r == -2 ){
    if(*cfg_verbose) CONSOLE.Debug("Connecting to tracker at %s", m_spec->url);
    m_status = DT_TRACKER_CONNECTING;
  }else{
    if(*cfg_verbose) CONSOLE.Debug("Connected to tracker at %s", m_spec->url);
    if( 0 == SendRequest() ) m_status = DT_TRACKER_READY;
    else{
      CLOSE_SOCKET(m_sock);
      m_sock = INVALID_SOCKET;
      return -1;
    }
  }
  return 0;
}
Example #6
0
int main(int argc, char *argv[])
{
	pid_t child_pid;
	int child_exit_status;
	struct termios tty_attr;
	struct winsize window_size;
	int pty_master;

	/* for select */
	fd_set readfds;
	fd_set writefds;

	unsigned err_n_rpty = 0;
	unsigned err_n_wpty = 0;
	unsigned err_n_stdin = 0;
	unsigned err_n_stdout = 0;

	int done = 0;

	/* the ring buffers */
	char inbuf_mem[BUFSIZE];
	char outbuf_mem[BUFSIZE];
	struct ring_buffer inbuf;
	struct ring_buffer outbuf;
	rb_init(&inbuf, inbuf_mem, sizeof(inbuf_mem));
	rb_init(&outbuf, outbuf_mem, sizeof(outbuf_mem));

	if (argc == 1) {
		printf("usage: %s PROGRAM [ARGS]...\n", argv[0]);
		exit(1);
	}

	/* We need I/O calls to fail with EINTR on SIGCHLD... */
	if (signal(SIGCHLD, sigchld_handler) == SIG_ERR) {
		perror("signal(SIGCHLD,...)");
		exit(EX_OSERR);
	}

	if (isatty(STDIN_FILENO)) {
		/* get terminal parameters associated with stdout */
		if (tcgetattr(STDOUT_FILENO, &tty_attr) < 0) {
			perror("tcgetattr(stdout,...)");
			exit(EX_OSERR);
		}

		/* get window size */
		if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &window_size) < 0) {
			perror("ioctl(stdout,...)");
			exit(1);
		}

		child_pid = forkpty(&pty_master, NULL, &tty_attr, &window_size);
	} else { /* not interactive */
		child_pid = forkpty(&pty_master, NULL, NULL, NULL);
	}

	if (child_pid < 0) {
		perror("forkpty()");
		exit(EX_OSERR);
	}
	if (child_pid == 0) { /* in the child */
		struct termios s_tty_attr;
		if (tcgetattr(STDIN_FILENO, &s_tty_attr)) {
			perror("tcgetattr(stdin,...)");
			exit(EXIT_FAILURE);
		}
		/* Turn off echo */
		s_tty_attr.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
		/* Also turn of NL to CR?LF on output */
		s_tty_attr.c_oflag &= ~(ONLCR);
		if (tcsetattr(STDIN_FILENO, TCSANOW, &s_tty_attr)) {
			perror("tcsetattr(stdin,...)");
			exit(EXIT_FAILURE);
		}

		if (execvp(argv[1], argv + 1)) {
			perror("execvp()");
			exit(EXIT_FAILURE);
		}
	}

	/* Non blocking mode for all file descriptors. */
	setfd_nonblock(pty_master);
	setfd_nonblock(STDIN_FILENO);
	setfd_nonblock(STDOUT_FILENO);

	if (isatty(STDIN_FILENO)) {
		if (tty_semi_raw(STDIN_FILENO) < 0) {
			perror("tty_semi_raw(stdin)");
		}
		if (atexit(tty_atexit) < 0) {
			perror("atexit()");
		}
	}

	do {
		/* Accept events only on fds, that we can handle now. */
		int do_select = 0;
		FD_ZERO(&readfds);
		FD_ZERO(&writefds);

		if (rb_space(&outbuf) > 0 && err_n_rpty < MAXRETR) {
			FD_SET(pty_master, &readfds);
			do_select = 1;
		}

		if (!rb_isempty(&inbuf) && err_n_wpty < MAXRETR) {
			FD_SET(pty_master, &writefds);
			do_select = 1;
		}

		if (rb_space(&inbuf) > 0 && err_n_stdin < MAXRETR) {
			FD_SET(STDIN_FILENO, &readfds);
			do_select = 1;
		}

		if (!rb_isempty(&outbuf) && err_n_stdout < MAXRETR) {
			FD_SET(STDOUT_FILENO, &writefds);
			do_select = 1;
		}

		if (!do_select) {
#ifdef DEBUG
			fprintf(stderr, "No I/O job for us, calling waitpid()...\n");
#endif
			while (waitpid(child_pid, &child_exit_status, 0) < 0)
			{
				/* nothing */
			}
			break;
		}

		errno = 0;
		int select_rc = select(pty_master + 1, &readfds, &writefds, NULL, NULL);
		if (select_rc < 0 && errno != EINTR) {
			perror("select()");
			exit(EX_IOERR);
		}
#ifdef DEBUG
		fprintf(stderr, "select() returned %d\n", select_rc);
#endif

		if (FD_ISSET(STDOUT_FILENO, &writefds)) {
#ifdef DEBUG
			fprintf(stderr, "stdout can be written\n");
#endif
			ssize_t n = rb_write(&outbuf, STDOUT_FILENO);
			if (n <= 0 && n != EINTR && n != EAGAIN)
				err_n_stdout++;
#ifdef DEBUG
			if (n >= 0)
				fprintf(stderr, "%d bytes written into stdout\n", n);
			else
				perror("write(stdout,...)");
#endif
		}

		if (FD_ISSET(pty_master, &writefds)) {
#ifdef DEBUG
			fprintf(stderr, "pty_master can be written\n");
#endif
			ssize_t n = rb_write(&inbuf, pty_master);
			if (n <= 0 && n != EINTR && n != EAGAIN)
				err_n_wpty++;
#ifdef DEBUG
			if (n >= 0)
				fprintf(stderr, "%d bytes written into pty_master\n", n);
			else
				perror("write(pty_master,...)");
#endif
		}

		if (FD_ISSET(STDIN_FILENO, &readfds)) {
#ifdef DEBUG
			fprintf(stderr, "stdin can be read\n");
#endif
			ssize_t n = rb_read(&inbuf, STDIN_FILENO);
			if (n <= 0 && n != EINTR && n != EAGAIN)
				err_n_stdin++;
#ifdef DEBUG
			if (n >= 0)
				fprintf(stderr, "%d bytes read from stdin\n", n);
			else
				perror("read(stdin,...)");
#endif
		}

		if (FD_ISSET(pty_master, &readfds)) {
#ifdef DEBUG
			fprintf(stderr, "pty_master can be read\n");
#endif
			ssize_t n = rb_read(&outbuf, pty_master);
			if (n <= 0 && n != EINTR && n != EAGAIN)
				err_n_rpty++;
#ifdef DEBUG
			if (n >= 0)
				fprintf(stderr, "%d bytes read from pty_master\n", n);
			else
				perror("read(pty_master,...)");
#endif
		}

		if (!done && waitpid(child_pid, &child_exit_status, WNOHANG) > 0)
			done = 1;

	} while (!done
		|| !(rb_isempty(&inbuf) || err_n_wpty >= MAXRETR)
		|| !(rb_isempty(&outbuf) || err_n_stdout >= MAXRETR));

#ifdef DEBUG
	fprintf(stderr, "inbuf: %u bytes left, outbuf: %u bytes left\n", inbuf.count, outbuf.count);
	fprintf(stderr, "err_n_rpty=%u, err_n_wpty=%u, err_n_stdin=%u, err_n_stdout=%u\n",
		err_n_rpty, err_n_wpty, err_n_stdin, err_n_stdout);
#endif

	if (WIFEXITED(child_exit_status))
		exit(WEXITSTATUS(child_exit_status));
	else if (WIFSIGNALED(child_exit_status))
		exit(128 + WTERMSIG(child_exit_status));

	exit(EXIT_FAILURE);
}