Ejemplo n.º 1
0
int
libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
{
        cfs_socket_t   *newsock;
        int             rc;

        newsock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
        if (!newsock) {
                CERROR("Can't allocate cfs_socket.\n");
                return -ENOMEM;
        }
        newsock->s_magic = CFS_SOCK_MAGIC;
        /*
         * thread will sleep in sock_accept by calling of msleep(), 
         * it can be interrupted because msleep() use PCATCH as argument.
         */
        rc = -sock_accept(C2B_SOCK(sock), NULL, 0, 0, 
                          libcfs_sock_upcall, newsock, &C2B_SOCK(newsock));
        if (rc) {
                if (C2B_SOCK(newsock) != NULL) 
                        sock_close(C2B_SOCK(newsock));
                FREE(newsock, M_TEMP);
                if ((sock->s_flags & CFS_SOCK_DOWN) != 0)
                        /* shutdown by libcfs_sock_abort_accept(), fake 
                         * error number for lnet_acceptor() */
                        rc = -EAGAIN;
                return rc;
        }
        *newsockp = newsock;
        return 0;
}
Ejemplo n.º 2
0
static connection_t *_accept_connection(void)
{
    int sock;
    connection_t *con;
    char *ip;
    int serversock; 

    serversock = wait_for_serversock(100);
    if(serversock < 0)
        return NULL;

    /* malloc enough room for a full IP address (including ipv6) */
    ip = (char *)malloc(MAX_ADDR_LEN);

    sock = sock_accept(serversock, ip, MAX_ADDR_LEN);
    if (sock >= 0)
    {
        con = connection_create (sock, serversock, ip);
        if (con == NULL)
            free (ip);

        return con;
    }

    if (!sock_recoverable(sock_error()))
        WARN2("accept() failed with error %d: %s", sock_error(), strerror(sock_error()));
    
    free(ip);

    return NULL;
}
Ejemplo n.º 3
0
int maccept(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
{
    int t;
    Word ipid;
    int xerrno;
    
    int *newfd = (int *)p1;
    selwakeupfx fx = (selwakeupfx)p2;
    xsockaddr_in *addr = (xsockaddr_in *)p3;
    int *addrlen = (int *)p4;
    
    
    if (Debug > 0)
    {
        s16_debug_printf("accept");
    }
    
    
    if (e->_TYPE != SOCK_STREAM) return EOPNOTSUPP;


    xerrno = sock_accept(e, newfd, fx, addr, addrlen);
    
    if (xerrno != EAGAIN || e->_NONBLOCK)
    {
        return xerrno;
    }
    
    
    for (;;)
    {
        xerrno = queue_command(e, kCommandAccept, 0, 0);
        if (xerrno == EINTR) return EINTR;
        if (xerrno) return EIO;
        
        if (e->command) continue;  // reset to 0 if processed.

        xerrno = sock_accept(e, newfd, fx, addr, addrlen);

        if (xerrno != EAGAIN) return xerrno;        
    }


    return 0;
}
Ejemplo n.º 4
0
static int ftp_init_receive(const char *path, transfer_mode_t mode,
							ftp_transfer_func hookf)
{
	long rp = ftp->restart_offset;
	char *e;

	ftp->restart_offset = 0L;

	foo_hookf = hookf;
	reset_transfer_info();

	if(ftp_init_transfer() != 0)
		return -1;

	ftp_type(mode);

	if(rp > 0) {
		/* fp is assumed to be fseek'd already */
		ftp_cmd("REST %ld", rp);
		if(ftp->code != ctContinue)
			return -1;
		ftp->ti.size = rp;
		ftp->ti.restart_size = rp;
	}

	ftp_cmd("RETR %s", path);
	if(ftp->code != ctPrelim)
		return -1;

	if(!sock_accept(ftp->data, "r", ftp_is_passive())) {
		ftp_err(_("data connection not accepted\n"));
		return -1;
	}

	/* try to get the total file size */
	{
		/* see if we have cached this directory/file */
		rfile *f = ftp_cache_get_file(path);
		if(f)
			ftp->ti.total_size = f->size;
		else {
			/* try to figure out file size from RETR reply
			 * Opening BINARY mode data connection for foo.mp3 (14429793 bytes)
			 *                                                  ^^^^^^^^ aha!
			 *
			 * note: this might not be the _total_ filesize if we are RESTarting
			 */
			e = strstr(ftp->reply, " bytes");
			if(e != 0) {
				while((e > ftp->reply) && isdigit((int)e[-1]))
					e--;
				ftp->ti.total_size = strtoul(e,NULL,10);
			} /* else we don't bother */
		}
	}
	return 0;
}
Ejemplo n.º 5
0
void * runner(void * args) {
	pthread_mutex_t lock; pthread_mutex_init(&lock, NULL);
	int sfd, nusfd, usfd = init_sockbind("/tmp/sockpath0");
	nusfd = sock_accept(usfd);
	if(nusfd < 0) {
		perror("sock_accept() ");
	}
	close(usfd);
	close(nusfd);
}
Ejemplo n.º 6
0
int main(int argc, char const *argv[]) {
	int usfd, nusfd, nsfd, sfd, i, j, len;
	pthread_t pid;
	pthread_mutex_init(&lock, NULL);
	usfd = init_sockbind("/tmp/sockpath");
	if(usfd < 0) {
		perror("init_sockbind() ");
		exit(1);
	}
	sfd = tcpsocket_bind(8001);
	if(sfd < 0) {
		perror("tcpsocket_bind() ");
		exit(2);
	}
	nusfd = sock_accept(usfd);
	if(nusfd < 0) {
		perror("sock_accept() ");
		exit(3);
	}

	struct ucred cred;
	len = sizeof(struct ucred);
	
	if(getsockopt(nusfd, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) {
		perror("getsockopt() ");
		exit(4);
	}
	// printf("%ld\n", (long) cred.pid); // backup server pid
	pthread_create(&pid, NULL, &runner, NULL);
	while(1) {
		nsfd = tcp_accept(sfd);
		if(nsfd < 0) {
			perror("tcp_accept() ");
			continue;
		}
		if(nsfd_cnt == MAXF) {
			for (i = 0; i < MAXF; ++i) {
				pthread_mutex_lock(&lock);
				if(send_fd(nusfd, nsfds[i]) < 0) {
					perror("send_fd() ");
				}
				pthread_mutex_unlock(&lock);
				// close(nsfds[i]);
			}
			nsfd_cnt = 0;
			sleep(2);
			kill(cred.pid, SIGUSR1);
		}
		pthread_mutex_lock(&lock);
		nsfds[nsfd_cnt++] = nsfd;
		pthread_mutex_unlock(&lock);
	}
	return 0;
}
Ejemplo n.º 7
0
unsigned int ZION_CALLBACK TcpThreadFunc(void * point)
{
	char *p = (char*)point;
	SOCK_HANDLE handle;
	SOCK_ADDR  sock_addr;
	char read_buf[1024];

	sock_init();
	if(sock_str2addr(p, &sock_addr)==NULL) 
	{
		printf("tcp sock_str2addr function error\n");
		goto FINISH_STATE;
	}


	handle = sock_bind(&sock_addr, 0);
	if(handle == SOCK_INVALID_HANDLE)
	{
		printf("tcp bind function error\n");
		goto ERROR_STATE;
	}

	printf("tcp %s wait for client connect....\n", p);

	handle =  sock_accept(handle, NULL);
	if(handle == SOCK_INVALID_HANDLE)
	{
		printf("tcp socket_accept function error\n");
		goto ERROR_STATE;
	}

	printf("tcp client connect access\n");

	while(1)
	{
		memset(read_buf, 0, sizeof(read_buf));
		//sock_readbuf(handle, (void*)read_buf, sizeof(read_buf));
		sock_read(handle, (void*)read_buf, sizeof(read_buf));
		printf("tcp client send '%s'\n", read_buf);
		sock_write(handle, (void*)read_buf, (int)strlen(read_buf));
	}


ERROR_STATE:
	sock_unbind(handle);
FINISH_STATE:
	sock_final();

	return 0;
}
Ejemplo n.º 8
0
int main(int argc, char *argv[]){
    int sfd;
    sfd = tcpsock_create();
    sock_setopt(sfd);
    sock_listen(sfd, SERVER_PORT, BACKLOG);
    fd_setnb(sfd);

    int evfd;
    evfd = ev_create();
    ev_add(evfd, sfd, EV_IN);

    struct ev_event events[MAX_EVENT];
    int n;
    int i;
    int cfd;
    unsigned char buf[BUF_SIZE];
    ssize_t rbytes;
    while(1) {
        n = ev_wait(evfd, events, MAX_EVENT, -1);
        printf("%d\n", n);
        for(i=0; i < n; i++){
            printf("%d, %d, %d, %d, %d\n", events[i].events, events[i].fd, events[i].readable, events[i].writable, events[i].closable);
            if (events[i].fd == sfd) {
                while(1) {
                    cfd = sock_accept(sfd);
                    if (cfd == -1) {
                        break;
                    }
                    fd_setnb(cfd);
                    ev_add(evfd, cfd, EV_IN);
                }
            } else if (events[i].closable == true) {
                close(events[i].fd);
            } else if (events[i].readable == true) {
                while(1) {
                    rbytes = sock_recv(events[i].fd, buf, BUF_SIZE);
                    if (rbytes == -1) {
                        break;
                    }
                    buf[rbytes] = '\0';
                    printf("%s", buf);
                }
            }
        }
    }
}
Ejemplo n.º 9
0
int ftp_list(const char *cmd, const char *param, FILE *fp)
{
  if (!cmd || !fp || !ftp_connected())
    return -1;

#ifdef HAVE_LIBSSH
  if (ftp->session)
    return ssh_list(cmd, param, fp);
#endif

  reset_transfer_info();
  foo_hookf = NULL;

#if 0 /* don't care about transfer type, binary should work well... */
  ftp_type(tmAscii);
#endif

  if (ftp_init_transfer() != 0) {
    ftp_err(_("transfer initialization failed"));
    return -1;
  }

  ftp_set_tmp_verbosity(vbNone);
  if (param)
    ftp_cmd("%s %s", cmd, param);
  else
    ftp_cmd("%s", cmd);
  if (ftp->code != ctPrelim)
    return -1;

  if (!sock_accept(ftp->data, "r", ftp_is_passive())) {
    perror("accept()");
    return -1;
  }

  if (FILE_recv_ascii(ftp->data, fp) != 0)
    return -1;

  sock_destroy(ftp->data);
  ftp->data = NULL;

  ftp_read_reply();

  return ftp->code == ctComplete ? 0 : -1;
}
Ejemplo n.º 10
0
int main(int argc, char const *argv[]) {
	pthread_t pid;
	pthread_mutex_init(&lock, NULL);
	int usfd, nusfd, sfd, n, _tmp_usfd = -1; char buf[BUFSIZE];
	usfd = init_sockbind("/tmp/sockpath1");
	if(usfd < 0) {
		perror("init_sockbind() ");
		exit(1);
	}
	pthread_create(&pid, NULL, &runner, NULL);
	nusfd = sock_accept(usfd);
	if(nusfd < 0) {
		perror("sock_accept() ");
		exit(1);
	}
	while(1) {
		int nsfd = recv_fd(nusfd);
		if(nsfd < 0) {
			perror("recv_fd() ");
			continue;
		}
		if(nsfd_cnt == MAXF) {
			if(_tmp_usfd < 0) {
				strcpy(buf, "/tmp/sockpath2");
				_tmp_usfd = init_sockconnect(buf);
				if(_tmp_usfd < 0) {
					perror("init_sockconnect() ");
				}
			}
			if(_tmp_usfd > 0) {
				if(send_fd(_tmp_usfd, nsfd) < 0) {
					perror("send_fd() ");
				}
			}
			printf("client forwarded !\n");
			continue;
		}
		// pthread_mutex_lock(&lock);
		write(nsfd, "C Multiplex", 11);
		nsfds[nsfd_cnt++] = nsfd;
		// pthread_mutex_unlock(&lock);
		printf("client added !\n");
	}
	return 0;
}
Ejemplo n.º 11
0
/*! \breif Receive an incoming connection */
static void hs_accept(void* _server) {
    Socket* client;
    HttpServer* server = _server;

    /* accept the conenction */
    client = sock_accept(server->sock);

    /* check for error */
    if(client == NULL) {
        return;
    }

    log(INFO, "New connection accepted %p", server->sock);

    /* create the http connection */
    hc_create(server, client);

}
Ejemplo n.º 12
0
static void
shell_connectback (long host, int port, long dest,
		   char *packet, int packet_len)
{
    int sock;
    int new_sock;

    sock = sock_tcp_create ();
    if (sock < 0)
    {
	perror ("[-] Error creating socket");
	return;
    }

    /* we bind before sending the payload to avoid not being
     * listening when the connectback shellcode tries to connect
     */
    if (sock_bind (sock, host, port) < 0)
    {
	perror ("[-] Unable to bind/listen");
	return;
    }

    if (sock_send_payload (dest, port, packet, packet_len) < 0)
    {
	perror ("[-] Unable to send payload");
	return;
    }

    printf ("[-] Waiting 10s for incoming connection (connectback)...\n");
    fflush (stdout);

    new_sock = sock_accept (sock);
    if (new_sock < 0)
    {
	perror ("[-] Unable to accept connection");
	return;
    }

    sock_disconnect (sock);

    shell (new_sock);
    sock_disconnect (new_sock);
}
Ejemplo n.º 13
0
static connection_t *_accept_connection(int duration)
{
    sock_t sock, serversock;
    char *ip;

    serversock = wait_for_serversock (duration);
    if (serversock == SOCK_ERROR)
        return NULL;

    /* malloc enough room for a full IP address (including ipv6) */
    ip = (char *)malloc(MAX_ADDR_LEN);

    sock = sock_accept(serversock, ip, MAX_ADDR_LEN);
    if (sock != SOCK_ERROR)
    {
        connection_t *con = NULL;
        /* Make any IPv4 mapped IPv6 address look like a normal IPv4 address */
        if (strncmp (ip, "::ffff:", 7) == 0)
            memmove (ip, ip+7, strlen (ip+7)+1);

        if (accept_ip_address (ip))
            con = connection_create (sock, serversock, ip);
        if (con)
            return con;
        sock_close (sock);
    }
    else
    {
        if (!sock_recoverable(sock_error()))
        {
            WARN2("accept() failed with error %d: %s", sock_error(), strerror(sock_error()));
            thread_sleep (500000);
        }
    }
    free(ip);
    return NULL;
}
Ejemplo n.º 14
0
void Server(char *Address, char *Port, int AddressFamily, int TransportProtocol)
{
char ErrBuf[1024];
char DataBuffer[1024];
int ServerSocket, ChildSocket;	// keeps the socket ID for this connection
struct addrinfo Hints;			// temporary struct to keep settings needed to open the new socket
struct addrinfo *AddrInfo;		// keeps the addrinfo chain; required to open a new socket
struct sockaddr_storage From;	// temp variable that keeps the parameters of the incoming connection
int ReadBytes;					// Number of bytes read from the socket
char RemoteAddress[1024];				// temp variable to store the address of the connecting host
char RemotePort[1024];				// temp variable to store the port used by the connecting host

	// Prepare to open a new server socket
	memset(&Hints, 0, sizeof(struct addrinfo));

	Hints.ai_family= AddressFamily;
	Hints.ai_socktype= TransportProtocol;	// Open a TCP/UDP connection
	Hints.ai_flags = AI_PASSIVE;		// This is a server: ready to bind() a socket 

	if (sock_initaddress (Address, Port, &Hints, &AddrInfo, ErrBuf, sizeof(ErrBuf)) == sockFAILURE)
	{
		printf("Error resolving given address/port: %s\n\n", ErrBuf);
		return;
	}

	printf("Server waiting on address %s, port %s, using protocol %s\n", 
		Address ? Address : "all local addresses", Port, (AddrInfo->ai_family == AF_INET) ? "IPv4" : "IPv6");
 
	if ( (ServerSocket= sock_open(AddrInfo, 1, 10,  ErrBuf, sizeof(ErrBuf))) == sockFAILURE)
	{
		// AddrInfo is no longer required
		sock_freeaddrinfo(AddrInfo);
		printf("Cannot opening the socket: %s\n\n", ErrBuf);
		return;
	}

	// AddrInfo is no longer required
	sock_freeaddrinfo(AddrInfo);

	if (TransportProtocol == SOCK_STREAM)
	{
		if ( (ChildSocket= sock_accept(ServerSocket, &From, ErrBuf, sizeof(ErrBuf))) == sockFAILURE)
		{
			printf("Error when accepting a new connection: %s\n\n", ErrBuf);
			return;
		}

		if (sock_getascii_addrport(&From, RemoteAddress, sizeof(RemoteAddress), RemotePort, sizeof(RemotePort),
			NI_NUMERICHOST | NI_NUMERICSERV, ErrBuf, sizeof(ErrBuf)) == sockFAILURE)
		{
			printf("Error getting information related to the connecting host: %s\n\n", ErrBuf);
			return;
		}
		printf("Accepting a new connection from host %s, using remote port %s.\n\n", RemoteAddress, RemotePort);

		ReadBytes= sock_recv(ChildSocket, DataBuffer, sizeof(DataBuffer), SOCK_RECEIVEALL_NO, 30, ErrBuf, sizeof(ErrBuf));
		if (ReadBytes == sockFAILURE)
		{
			printf("Error reading data: %s\n\n", ErrBuf);
			return;
		}
	}
	else
	{
		ReadBytes= sock_recvdgram(ServerSocket, DataBuffer, sizeof(DataBuffer), SOCK_RECEIVEALL_NO, 30, ErrBuf, sizeof(ErrBuf));
		if (ReadBytes == sockFAILURE)
		{
			printf("Error reading data: %s\n\n", ErrBuf);
			return;
		}
	}

	if (ReadBytes == sockWARNING)
	{
		printf("We waited for enough time and no data has been received so far.\nAborting the connection.\n\n");
		return;
	}

	// Terminate buffer, just for printing purposes
	// Warning: this can originate a buffer overflow
	DataBuffer[ReadBytes]= 0;
	printf("Received the following string: '%s'\n\n", DataBuffer);
}
Ejemplo n.º 15
0
// The main function
int
main(int argc, char **argv)
{
    // Read in argc
    int i;
    int num_servers;
    int portno;
    char *backend_hosts[MAX_SERVERS];
    int backend_port[MAX_SERVERS];
    int weights[MAX_SERVERS];

    // if not enough number of servers or too many servers
    num_servers = (argc - 2) / 3;
    if (argc < 4 || num_servers > MAX_SERVERS || (argc - 2) % 3) {
        fprintf(stderr, "Usage: %s PROXY_PORTNO [BACKEND_ADDR PORTNO WEIGHT]...\n"
                "MAX server num: %d\n", argv[0], MAX_SERVERS);
        exit(1);
    }

    // Read in configs
    portno = atoi(argv[1]);
    for (i = 0; i < num_servers; ++i) {
        int host_index = i * 3 + 2;

        backend_hosts[i] = argv[host_index];
        backend_port[i] = atoi(argv[host_index + 1]);
        weights[i] = atoi(argv[host_index + 2]);

#ifdef DEBUG
        printf("[DEBUG] server %s:%d weight %d\n",
               backend_hosts[i],
               backend_port[i],
               weights[i]);
#endif
    }

    // Start server procedure
    // setup network, start server
    int serverfd;
    server_conf_t server_conf;
    balancer_t balancer;
    unsigned backend_rotate;
    threadpool_t *pool;

    // Init balancer
    balancer_init(&balancer, num_servers, weights);

    // Init thread pool
    pool = threadpool_create(THREAD_NUM, THREADPOOL_SIZE);

    // creating server thread pool
    printf("[INFO] Created server pool with %d threads and %d queue\n",
           THREAD_NUM, THREADPOOL_SIZE);

    // Init server config
    pthread_mutex_init(&(server_conf.lock), NULL);
    server_conf.total_conn = 0;
    for (i = 0; i < num_servers; ++i) {
        server_conf.connections[i] = 0;
    }

    // starting server procedure
    // Starting binding and listening
    printf("[INFO] Starting server procedure\n");
    if ((serverfd = socket(AF_INET,
                           SOCK_STREAM,
                           0)) < 0) {
        perror("[ERROR] Error creating socket\n");
        exit(1);
    }

    if (sock_bind_listen(serverfd, portno, MAX_CONNECT) < 0) {
        perror("[ERROR] Error binding and listening to socket\n");
        exit(1);
    }

    // Main loop
    while (1) {
        // accept new connection
        int clientfd;

        // setup server
        balancer_balance(&balancer, &server_conf);

        server_conf.index = balancer.index;
        server_conf.backend_host = backend_hosts[balancer.index];
        server_conf.backend_port = backend_port[balancer.index];

#ifdef DEBUG
        printf("[DEBUG] balancer index %d out of %d servers\n", balancer.index, balancer.server_num);
#endif

        // setup connection number
        pthread_mutex_lock(&(server_conf.lock));
        server_conf.connections[balancer.index]++;
        server_conf.total_conn++;
        pthread_mutex_unlock(&(server_conf.lock));

        // accept and new thread
        if ((clientfd = sock_accept(serverfd)) > 0) {

#ifdef DEBUG
            printf("[INFO] Accepting new connection\n");
#endif
           
            // hand new request to threads
            server_conf.clientsockfd = clientfd;

            threadpool_assign(pool, server_thread, (void *)&server_conf);
        }
    }

    // Gracefully shutting down
    threadpool_destroy(pool);

    // DEBUG
    printf("[INFO] closing procedure\n");

    pthread_mutex_destroy(&(server_conf.lock));

    return 0;
}
Ejemplo n.º 16
0
static client_t *accept_client (void)
{
    client_t *client = NULL;
    sock_t sock, serversock = wait_for_serversock ();
    char addr [200];

    if (serversock == SOCK_ERROR)
        return NULL;

    sock = sock_accept (serversock, addr, 200);
    if (sock == SOCK_ERROR)
    {
        if (sock_recoverable (sock_error()))
            return NULL;
        WARN2 ("accept() failed with error %d: %s", sock_error(), strerror(sock_error()));
        thread_sleep (500000);
        return NULL;
    }
    do
    {
        int i, num;
        refbuf_t *r;

        if (sock_set_blocking (sock, 0) || sock_set_nodelay (sock))
        {
            WARN0 ("failed to set tcp options on client connection, dropping");
            break;
        }
        client = calloc (1, sizeof (client_t));
        if (client == NULL || connection_init (&client->connection, sock, addr) < 0)
            break;

        client->shared_data = r = refbuf_new (PER_CLIENT_REFBUF_SIZE);
        r->len = 0; // for building up the request coming in

        global_lock ();
        client_register (client);

        for (i=0; i < global.server_sockets; i++)
        {
            if (global.serversock[i] == serversock)
            {
                client->server_conn = global.server_conn[i];
                client->server_conn->refcount++;
                if (client->server_conn->ssl && ssl_ok)
                    connection_uses_ssl (&client->connection);
                if (client->server_conn->shoutcast_compat)
                    client->ops = &shoutcast_source_ops;
                else
                    client->ops = &http_request_ops;
                break;
            }
        }
        num = global.clients;
        global_unlock ();
        stats_event_args (NULL, "clients", "%d", num);
        client->flags |= CLIENT_ACTIVE;
        return client;
    } while (0);

    free (client);
    sock_close (sock);
    return NULL;
}
Ejemplo n.º 17
0
/*
 * System call vectors. Since I (RIB) want to rewrite sockets as streams,
 * we have this level of indirection. Not a lot of overhead, since more of
 * the work is done via read/write/select directly.
 */
asmlinkage int
sys_socketcall(int call, unsigned long *args)
{
  int er;
  switch(call) {
	case SYS_SOCKET:
		er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
		if(er)
			return er;
		return(sock_socket(get_fs_long(args+0),
				   get_fs_long(args+1),
				   get_fs_long(args+2)));
	case SYS_BIND:
		er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
		if(er)
			return er;
		return(sock_bind(get_fs_long(args+0),
				 (struct sockaddr *)get_fs_long(args+1),
				 get_fs_long(args+2)));
	case SYS_CONNECT:
		er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
		if(er)
			return er;
		return(sock_connect(get_fs_long(args+0),
				    (struct sockaddr *)get_fs_long(args+1),
				    get_fs_long(args+2)));
	case SYS_LISTEN:
		er=verify_area(VERIFY_READ, args, 2 * sizeof(long));
		if(er)
			return er;
		return(sock_listen(get_fs_long(args+0),
				   get_fs_long(args+1)));
	case SYS_ACCEPT:
		er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
		if(er)
			return er;
		return(sock_accept(get_fs_long(args+0),
				   (struct sockaddr *)get_fs_long(args+1),
				   (int *)get_fs_long(args+2)));
	case SYS_GETSOCKNAME:
		er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
		if(er)
			return er;
		return(sock_getsockname(get_fs_long(args+0),
					(struct sockaddr *)get_fs_long(args+1),
					(int *)get_fs_long(args+2)));
	case SYS_GETPEERNAME:
		er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
		if(er)
			return er;
		return(sock_getpeername(get_fs_long(args+0),
					(struct sockaddr *)get_fs_long(args+1),
					(int *)get_fs_long(args+2)));
	case SYS_SOCKETPAIR:
		er=verify_area(VERIFY_READ, args, 4 * sizeof(long));
		if(er)
			return er;
		return(sock_socketpair(get_fs_long(args+0),
				       get_fs_long(args+1),
				       get_fs_long(args+2),
				       (unsigned long *)get_fs_long(args+3)));
	case SYS_SEND:
		er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
		if(er)
			return er;
		return(sock_send(get_fs_long(args+0),
				 (void *)get_fs_long(args+1),
				 get_fs_long(args+2),
				 get_fs_long(args+3)));
	case SYS_SENDTO:
		er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
		if(er)
			return er;
		return(sock_sendto(get_fs_long(args+0),
				   (void *)get_fs_long(args+1),
				   get_fs_long(args+2),
				   get_fs_long(args+3),
				   (struct sockaddr *)get_fs_long(args+4),
				   get_fs_long(args+5)));
	case SYS_RECV:
		er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
		if(er)
			return er;
		return(sock_recv(get_fs_long(args+0),
				 (void *)get_fs_long(args+1),
				 get_fs_long(args+2),
				 get_fs_long(args+3)));
	case SYS_RECVFROM:
		er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
		if(er)
			return er;
		return(sock_recvfrom(get_fs_long(args+0),
				     (void *)get_fs_long(args+1),
				     get_fs_long(args+2),
				     get_fs_long(args+3),
				     (struct sockaddr *)get_fs_long(args+4),
				     (int *)get_fs_long(args+5)));
	case SYS_SHUTDOWN:
		er=verify_area(VERIFY_READ, args, 2* sizeof(unsigned long));
		if(er)
			return er;
		return(sock_shutdown(get_fs_long(args+0),
				     get_fs_long(args+1)));
	case SYS_SETSOCKOPT:
		er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
		if(er)
			return er;
		return(sock_setsockopt(get_fs_long(args+0),
				       get_fs_long(args+1),
				       get_fs_long(args+2),
				       (char *)get_fs_long(args+3),
				       get_fs_long(args+4)));
	case SYS_GETSOCKOPT:
		er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
		if(er)
			return er;
		return(sock_getsockopt(get_fs_long(args+0),
				       get_fs_long(args+1),
				       get_fs_long(args+2),
				       (char *)get_fs_long(args+3),
				       (int *)get_fs_long(args+4)));
	default:
		return(-EINVAL);
  }
}
Ejemplo n.º 18
0
int udpclient(int argc, char *argv[])
{
    char *lhost, *lport, *phost, *pport, *rhost, *rport;
    list_t *clients = NULL;
    list_t *conn_clients;
    client_t *client;
    client_t *client2;
    socket_t *tcp_serv = NULL;
    socket_t *tcp_sock = NULL;
    socket_t *udp_sock = NULL;
    char data[MSG_MAX_LEN];
    char addrstr[ADDRSTRLEN];
    
    struct timeval curr_time;
    struct timeval check_time;
    struct timeval check_interval;
    struct timeval timeout;
    fd_set client_fds;
    fd_set read_fds;
    uint16_t tmp_id;
    uint8_t tmp_type;
    uint16_t tmp_len;
    uint16_t tmp_req_id;
    int num_fds;
    
    int ret;
    int i;
    
    signal(SIGINT, &signal_handler);

    i = 0;    
    lhost = (argc - i == 5) ? NULL : argv[i++];
    lport = argv[i++];
    phost = argv[i++];
    pport = argv[i++];
    rhost = argv[i++];
    rport = argv[i++];

    /* Check validity of ports (can't check ip's b/c might be host names) */
    ERROR_GOTO(!isnum(lport), "Invalid local port.", done);
    ERROR_GOTO(!isnum(pport), "Invalid proxy port.", done);
    ERROR_GOTO(!isnum(rport), "Invalid remote port.", done);
    
    srand(time(NULL));
    next_req_id = rand() % 0xffff;
    
    /* Create an empty list for the clients */
    clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
                          p_client_free, 1);
    ERROR_GOTO(clients == NULL, "Error creating clients list.", done);

    /* Create and empty list for the connecting clients */
    conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
                               p_client_free, 1);
    ERROR_GOTO(conn_clients == NULL, "Error creating clients list.", done);

    /* Create a TCP server socket to listen for incoming connections */
    tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1);
    ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done);
    if(debug_level >= DEBUG_LEVEL1)
    {
        printf("Listening on TCP %s\n",
               sock_get_str(tcp_serv, addrstr, sizeof(addrstr)));
    }
    
    FD_ZERO(&client_fds);

    /* Initialize all the timers */
    timerclear(&timeout);
    check_interval.tv_sec = 0;
    check_interval.tv_usec = 500000;
    gettimeofday(&check_time, NULL);
    
    while(running)
    {
        if(!timerisset(&timeout))
            timeout.tv_usec = 50000;

        read_fds = client_fds;
        FD_SET(SOCK_FD(tcp_serv), &read_fds);

        ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
        PERROR_GOTO(ret < 0, "select", done);
        num_fds = ret;

        gettimeofday(&curr_time, NULL);

        /* Go through all the clients and check if didn't get an ACK for sent
           data during the timeout period */
        if(timercmp(&curr_time, &check_time, >))
        {
            for(i = 0; i < LIST_LEN(clients); i++)
            {
                client = list_get_at(clients, i);

                ret = client_check_and_resend(client, curr_time);
                if(ret == -2)
                {
                    disconnect_and_remove_client(CLIENT_ID(client), clients,
                                                 &client_fds, 1);
                    i--;
                    continue;
                }

                ret = client_check_and_send_keepalive(client, curr_time);
                if(ret == -2)
                {
                    disconnect_and_remove_client(CLIENT_ID(client), clients,
                                                 &client_fds, 1);
                    i--;
                }
            }

            timeradd(&curr_time, &check_interval, &check_time);
        }
        
        if(num_fds == 0)
            continue;

        /* Check if pending TCP connection to accept and create a new client
           and UDP connection if one is ready */
        if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds))
        {
            tcp_sock = sock_accept(tcp_serv);
            if(tcp_sock == NULL)
                continue;
            udp_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1);
            if(udp_sock == NULL)
            {
                sock_close(tcp_sock);
                sock_free(tcp_sock);
                continue;
            }

            client = client_create(next_req_id++, tcp_sock, udp_sock, 1);
            if(!client || !tcp_sock || !udp_sock)
            {
                if(tcp_sock)
                    sock_close(tcp_sock);
                if(udp_sock)
                    sock_close(udp_sock);
            }
            else
            {
                client2 = list_add(conn_clients, client, 1);
                client_free(client);
                client = NULL;
                
                client_send_hello(client2, rhost, rport, CLIENT_ID(client2));
                client_add_tcp_fd_to_set(client2, &client_fds);
                client_add_udp_fd_to_set(client2, &client_fds);
            }
            
            sock_free(tcp_sock);
            sock_free(udp_sock);
            tcp_sock = NULL;
            udp_sock = NULL;

            num_fds--;
        }

        /* Check for pending handshakes from UDP connection */
        for(i = 0; i < LIST_LEN(conn_clients) && num_fds > 0; i++)
        {
            client = list_get_at(conn_clients, i);
            
            if(client_udp_fd_isset(client, &read_fds))
            {
                num_fds--;
                tmp_req_id = CLIENT_ID(client);

                ret = client_recv_udp_msg(client, data, sizeof(data),
                                          &tmp_id, &tmp_type, &tmp_len);
                if(ret == 0)
                    ret = handle_message(client, tmp_id, tmp_type,
                                         data, tmp_len);

                if(ret < 0)
                {
                    disconnect_and_remove_client(tmp_req_id, conn_clients,
                                                 &client_fds, 1);
                    i--;
                }
                else
                {
                    client = list_add(clients, client, 1);
                    list_delete_at(conn_clients, i);
                    client_remove_udp_fd_from_set(client, &read_fds);
                    i--;
                }
            }
        }

        /* Check if data is ready from any of the clients */
        for(i = 0; i < LIST_LEN(clients); i++)
        {
            client = list_get_at(clients, i);

            /* Check for UDP data */
            if(num_fds > 0 && client_udp_fd_isset(client, &read_fds))
            {
                num_fds--;

                ret = client_recv_udp_msg(client, data, sizeof(data),
                                          &tmp_id, &tmp_type, &tmp_len);
                if(ret == 0)
                    ret = handle_message(client, tmp_id, tmp_type,
                                         data, tmp_len);
                if(ret < 0)
                {
                    disconnect_and_remove_client(CLIENT_ID(client), clients,
                                                 &client_fds, 1);
                    i--;
                    continue; /* Don't go to check the TCP connection */
                }
            }

            /* Check for TCP data */
            if(num_fds > 0 && client_tcp_fd_isset(client, &read_fds))
            {
                ret = client_recv_tcp_data(client);
                if(ret == -1)
                {
                    disconnect_and_remove_client(CLIENT_ID(client), clients,
                                                 &client_fds, 1);
                    i--;
                    continue;
                }
                else if(ret == -2)
                {
                    client_mark_to_disconnect(client);
                    disconnect_and_remove_client(CLIENT_ID(client),
                                                 clients, &client_fds, 0);
                }

                num_fds--;
            }

            /* send any TCP data that was ready */
            ret = client_send_udp_data(client);
            if(ret < 0)
            {
                disconnect_and_remove_client(CLIENT_ID(client), clients,
                                             &client_fds, 1);
                i--;
            }
        }

        /* Finally, send any udp data that's still in the queue */
        for(i = 0; i < LIST_LEN(clients); i++)
        {
            client = list_get_at(clients, i);
            ret = client_send_udp_data(client);

            if(ret < 0 || client_ready_to_disconnect(client))
            {
                disconnect_and_remove_client(CLIENT_ID(client), clients,
                                             &client_fds, 1);
                i--;
            }
        }
    }
    
  done:
    if(debug_level >= DEBUG_LEVEL1)
        printf("Cleaning up...\n");
    if(tcp_serv)
    {
        sock_close(tcp_serv);
        sock_free(tcp_serv);
    }
    if(udp_sock)
    {
        sock_close(udp_sock);
        sock_free(udp_sock);
    }
    if(clients)
        list_free(clients);
    if(conn_clients)
        list_free(conn_clients);
    if(debug_level >= DEBUG_LEVEL1)
        printf("Goodbye.\n");
    return 0;
}
Ejemplo n.º 19
0
int main(int argc,char **argv)
{
	int opt,long_opt_index = 0,ret;
	struct netdev *vdev,dev;
	struct socket sk;
	u_char *ifconf;
	struct linger so_linger;
	u_int mtu=0;

	memset(&dev,0,sizeof(struct netdev));
	memset(&sk,0,sizeof(struct socket));
	ifconf = NULL;
	vdev = &dev;
	vdev->nd_ops = &nd_ops;
	vdev->sk = &sk;

	while( (opt =getopt_long(argc,argv,"hi:I:p:u:vm:H:K:d",long_opt,&long_opt_index)) != -1 ) {
		switch(opt) {
		case 'h':
			banner(argv[0]);
			break;
		case 'i':
			memcpy(&dev.nd_name,optarg,IFNAMSIZ-1);
			break;
		case 'I':
			ifconf = (u_char*)strdup(optarg);
			has_ifconf |=1;
			break;
		case 'p':
			sk.sk_port = atoi(optarg);
			break;
		case 'u':
			dev.nd_owner = (u_int8_t*)strdup(optarg);
			break;
		case 'v':
			verbose |= 1;
			break;
		case 'm':
			mtu = atoi(optarg);
			break;
		case 'K':
			shr_key = (unsigned char*)strdup(optarg);
			break;
		case 'H':
			hwaddr = (u_char *)strdup(optarg);
			break;
		case 'd':
			daemonize |=1;
			break;
		default:
			banner(argv[0]);
			break;
		}
	}
	
	/* device name is not required , 
	   the kernel will give us a random name  */
	dev.nd_flags = IFF_TAP | IFF_NO_PI;
	if(daemonize)
		if(daemon(0,0) == -1) {
			perrx("main():daemon()");
			return -1;
		}

	if(!has_ifconf ) {
		fprintf(stderr,"[!] Device configuration is not set \n");
	} else 
		parse_conf((char*)ifconf,&dev);

	if (!sk.sk_port) 
		sk.sk_port = DEFAULT_PORT;
	
	if(!mtu || mtu < 0 || mtu > 4096)
		vdev->nd_mtu = MTU;
	else
		vdev->nd_mtu = mtu;
	
	if(shr_key == NULL) {
		printf("[-] Shared key is not set\n");
		return -1;
	}
	sk.sk_fd = socket(AF_INET,SOCK_STREAM,0);
	if(sk.sk_fd < 0) {
		perror("main():socket()");
		return -1;
	}

	/* set linger socket option  */
	so_linger.l_onoff = 1;
	so_linger.l_linger = 0;
	
	ret = setsockopt(sk.sk_fd,SOL_SOCKET,SO_LINGER,&so_linger,sizeof(struct linger));
	if(ret == -1) {
		perror("main:setsockopt(SO_LINGER)");
		close(sk.sk_fd);
		return ret;
	}

	/* let's create a virtual device interface */
	if(vdev->nd_ops->init(&dev))
		return -1;
	
	int yes = 1;
	struct socket *sk_cli;
	
	sk.sk_serv.sin_family = AF_INET;
	sk.sk_serv.sin_port = htons(sk.sk_port);
	sk.sk_serv.sin_addr.s_addr = htonl(INADDR_ANY);
	
	/* enable socket address re-use */
	ret = setsockopt(sk.sk_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes));
	if(ret == -1) {
		perror("main:setsockopt(SO_REUSEADDR)");
		close(sk.sk_fd);
		return ret;
	}
	ret = bind(sk.sk_fd,(struct sockaddr*)&sk.sk_serv,sizeof(struct sockaddr_in));
	if(ret == -1) {
		perror("main:bind()");
		close(sk.sk_fd);
		return ret;
	}
	ret = listen(sk.sk_fd,4);
	if(ret == -1) {
		perror("main:listen()");
		return -1;
	}
	if(verbose) 
		printf("[+] Listening on port : %d\n",sk.sk_port);
	
	for(;;) {
		sk_cli =sock_accept(&dev);
		if(!sk_cli)  
			return -1;
		vdev->nd_ops->xmit(vdev,sk_cli);
	}
		
	vdev->nd_ops->exit(vdev);
	return 0;
}
Ejemplo n.º 20
0
int udpclient(int argc, char* argv[])
{
	char* lhost, *lport, *phost, *pport, *rhost, *rport;
	list_t* clients;
	list_t* conn_clients;
	client_t* client;
	client_t* client2;
	socket_t* tcp_serv = NULL;
	socket_t* tcp_sock = NULL;
	socket_t* udp_sock = NULL;
	char data[MSG_MAX_LEN];
	char addrstr[ADDRSTRLEN];
	char pport_s[6];
	struct timeval curr_time;
	struct timeval check_time;
	struct timeval check_interval;
	struct timeval timeout;
	fd_set client_fds;
	fd_set read_fds;
	uint16_t tmp_id;
	uint8_t tmp_type;
	uint16_t tmp_len;
	uint16_t tmp_req_id;
	int num_fds;
	int ret;
	int i;
	int icmp_sock ;
	int timeexc = -1;
	struct sockaddr_in src, dest, rsrc;
	struct hostent* hp;
	uint32_t timeexc_ip;
	signal(SIGINT, &signal_handler);
	i = 0;
	if(index(argv[i], 58) || index(argv[i], 46))
		lhost = argv[i++];
	else
		lhost = NULL;
	lport = argv[i++];
	phost = argv[i++];
	if(index(argv[i], 58) || index(argv[i], 46)) {
		snprintf(pport_s, 5, "2222");
		pport = pport_s;
	} else
		pport = argv[i++];
	rhost = argv[i++];
	rport = argv[i++];
	/* Get info about localhost IP */
	if(!lhost){
		char szHostName[255];
		gethostname(szHostName, 255);
		hp = gethostbyname(szHostName);
	}else{
		hp = gethostbyname(lhost);
	}
	memset(&rsrc, 0, sizeof(struct sockaddr_in));
	timeexc_ip				= *(uint32_t*)hp->h_addr_list[0];
	rsrc.sin_family			= AF_INET;
	rsrc.sin_port			= 0;
	rsrc.sin_addr.s_addr	= timeexc_ip;
	/* IP of destination */
	memset(&src, 0, sizeof(struct sockaddr_in));
	hp					  = gethostbyname(phost);
	timeexc_ip            = *(uint32_t*)hp->h_addr_list[0];
	src.sin_family        = AF_INET;
	src.sin_port          = 0;
	src.sin_addr.s_addr   = timeexc_ip;
	/* IP of where the fake packet (echo request) was going */
	hp = gethostbyname("3.3.3.3");
	memcpy(&dest.sin_addr, hp->h_addr, hp->h_length);
	inet_pton(AF_INET, "3.3.3.3", &(dest.sin_addr));
	srand(time(NULL));
	next_req_id = rand() % 0xffff;
	/* Create an empty list for the clients */
	clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
						  p_client_free);
	ERROR_GOTO(clients == NULL, "Error creating clients list.", done);
	/* Create and empty list for the connecting clients */
	conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
							   p_client_free);
	ERROR_GOTO(conn_clients == NULL, "Error creating clients list.", done);
	/* Create a TCP server socket to listen for incoming connections */
	tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1);
	ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done);
	if(debug_level >= DEBUG_LEVEL1) {
		printf("Listening on TCP %s\n",
			   sock_get_str(tcp_serv, addrstr, sizeof(addrstr)));
	}
	FD_ZERO(&client_fds);
	/* Initialize all the timers */
	timerclear(&timeout);
	check_interval.tv_sec = 0;
	check_interval.tv_usec = 500000;
	gettimeofday(&check_time, NULL);
	/* open raw socket */
	create_icmp_socket(&icmp_sock);
	if(icmp_sock == -1) {
		printf("[main] can't open raw socket\n");
		exit(1);
	}
	while(running) {
		if(!timerisset(&timeout))
			timeout.tv_usec = 50000;
		if(++timeexc==100) {
			timeexc=0;
			/* Send ICMP TTL exceeded to penetrate remote NAT */
			send_icmp(icmp_sock, &rsrc, &src, &dest, 0);
		}
		read_fds = client_fds;
		FD_SET(SOCK_FD(tcp_serv), &read_fds);
		ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
		PERROR_GOTO(ret < 0, "select", done);
		num_fds = ret;
		gettimeofday(&curr_time, NULL);
		/* Go through all the clients and check if didn't get an ACK for sent
		   data during the timeout period */
		if(timercmp(&curr_time, &check_time, >)) {
			for(i = 0; i < LIST_LEN(clients); i++) {
				client = list_get_at(clients, i);
				ret = client_check_and_resend(client, curr_time);
				if(ret == -2) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
					continue;
				}
				ret = client_check_and_send_keepalive(client, curr_time);
				if(ret == -2) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
				}
			}
			timeradd(&curr_time, &check_interval, &check_time);
		}
		if(num_fds == 0) continue;
		timeexc=0;
		/* Check if pending TCP connection to accept and create a new client
		   and UDP connection if one is ready */
		if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) {
			tcp_sock = sock_accept(tcp_serv);
			udp_sock = sock_create(phost, pport, ipver,
								   SOCK_TYPE_UDP, 0, 1);
			client = client_create(next_req_id++, tcp_sock, udp_sock, 1);
			if(!client || !tcp_sock || !udp_sock) {
				if(tcp_sock)
					sock_close(tcp_sock);
				if(udp_sock)
					sock_close(udp_sock);
			} else {
				client2 = list_add(conn_clients, client);
				client_free(client);
				client = NULL;
				client_send_hello(client2, rhost, rport, CLIENT_ID(client2));
				client_add_tcp_fd_to_set(client2, &client_fds);
				client_add_udp_fd_to_set(client2, &client_fds);
			}
			sock_free(tcp_sock);
			sock_free(udp_sock);
			tcp_sock = NULL;
			udp_sock = NULL;
			num_fds--;
		}
		/* Check for pending handshakes from UDP connection */
		for(i = 0; i < LIST_LEN(conn_clients) && num_fds > 0; i++) {
			client = list_get_at(conn_clients, i);
			if(client_udp_fd_isset(client, &read_fds)) {
				num_fds--;
				tmp_req_id = CLIENT_ID(client);
				ret = client_recv_udp_msg(client, data, sizeof(data),
										  &tmp_id, &tmp_type, &tmp_len);
				if(ret == 0)
					ret = handle_message(client, tmp_id, tmp_type,
										 data, tmp_len);
				if(ret < 0) {
					disconnect_and_remove_client(tmp_req_id, conn_clients,
												 &client_fds);
					i--;
				} else {
					client = list_add(clients, client);
					list_delete_at(conn_clients, i);
					client_remove_udp_fd_from_set(client, &read_fds);
					i--;
				}
			}
		}
		/* Check if data is ready from any of the clients */
		for(i = 0; i < LIST_LEN(clients) && num_fds > 0; i++) {
			client = list_get_at(clients, i);
			/* Check for UDP data */
			if(client_udp_fd_isset(client, &read_fds)) {
				num_fds--;
				ret = client_recv_udp_msg(client, data, sizeof(data),
										  &tmp_id, &tmp_type, &tmp_len);
				if(ret == 0)
					ret = handle_message(client, tmp_id, tmp_type,
										 data, tmp_len);
				if(ret < 0) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
					continue; /* Don't go to check the TCP connection */
				}
			}
			/* Check for TCP data */
			if(client_tcp_fd_isset(client, &read_fds)) {
				num_fds--;
				ret = client_recv_tcp_data(client);
				if(ret == 0)
					ret = client_send_udp_data(client);
#if 0 /* if udptunnel is taking up 100% of cpu, try including this */
				else if(ret == 1)
#ifdef _WIN32
					_sleep(1);
#else
					usleep(1000); /* Quick hack so doesn't use 100% of CPU if
                                     data wasn't ready yet (waiting for ack) */
#endif /*WIN32*/
#endif /*0*/
				if(ret < 0) {
					disconnect_and_remove_client(CLIENT_ID(client), clients,
												 &client_fds);
					i--;
				}
			}
		}
	}
done:
	if(debug_level >= DEBUG_LEVEL1)
		printf("Cleaning up...\n");
	if(tcp_serv) {
		sock_close(tcp_serv);
		sock_free(tcp_serv);
	}
	if(udp_sock) {
		sock_close(udp_sock);
		sock_free(udp_sock);
	}
	if(clients)
		list_free(clients);
	if(debug_level >= DEBUG_LEVEL1)
		printf("Goodbye.\n");
	return 0;
}
Ejemplo n.º 21
0
/**
 * Create a new socket accepting a new connection from a listening socket.
 * @param main Listening socket.
 * @param octx optional ssl global context
 * @return the newly allocated Sock
 */
Sock * Sock_accept(Sock *s, void * octx)
{
    int res = -1;
    char remote_host[128]; /*Unix Domain is largest*/
    char local_host[128]; /*Unix Domain is largest*/
    int remote_port = -1;
    int local_port = -1;
    Sock *new_s = NULL;
    struct sockaddr *sa_p = NULL;
    socklen_t sa_len = 0;

#if ENABLE_SSL
    SSL_CTX * ctx = octx;
    SSL *ssl_con = NULL;
#endif

    if (!s)
        return NULL;

    if ((res = sock_accept(s->fd)) < 0) {
        net_log(NET_LOG_ERR, "System error in sock_accept().\n");
        return NULL;
    }

#if ENABLE_SSL
    if(ctx) {
        if( !(ssl_con = SSL_sock_accept(res, ctx)) ) {
            net_log(NET_LOG_ERR, "Unable to accept SSL connection.\n");
            sock_close(res);
            return NULL;
        }
    }
#endif

    if (!(new_s = calloc(1, sizeof(Sock)))) {
        net_log(NET_LOG_FATAL,
                "Unable to allocate a Sock struct in Sock_accept().\n");
#if ENABLE_SSL
        if(ctx)
            SSL_close_connection(ssl_con, res);
#endif
        sock_close(res);
        return NULL;
    }

    new_s->fd = res;
    new_s->socktype = s->socktype;
    new_s->flags = s->flags;

#if ENABLE_SSL
    if(ctx)
        new_s->ssl = ssl_con;
#endif

    sa_p = (struct sockaddr *) &(new_s->remote_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getpeername(res, sa_p, &sa_len))
    {
        net_log(NET_LOG_ERR,
                "Unable to get remote address in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, remote_host, sizeof(remote_host)))
        memset(remote_host, 0, sizeof(remote_host));

    if (!(new_s->remote_host = strdup(remote_host))) {
        net_log(NET_LOG_FATAL,
                "Unable to allocate remote host in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }

    remote_port = sock_get_port(sa_p);
    if(remote_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get remote port in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }
    else
        new_s->remote_port = ntohs(remote_port);

    sa_p = (struct sockaddr *) &(new_s->remote_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getsockname(res, sa_p, &sa_len))
    {
        net_log(NET_LOG_ERR, "Unable to get remote port in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, local_host, sizeof(local_host)))
        memset(local_host, 0, sizeof(local_host));

    if (!(new_s->local_host = strdup(local_host))) {
        net_log(NET_LOG_FATAL,
                "Unable to allocate local host in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }

    local_port = sock_get_port(sa_p);
    if(local_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get local port in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }
    else
        new_s->local_port = ntohs(local_port);

    net_log(NET_LOG_DEBUG, "Socket accepted between local=\"%s\":%u and "
        "remote=\"%s\":%u.\n", new_s->local_host, new_s->local_port,
        new_s->remote_host, new_s->remote_port);

    return new_s;
}
Ejemplo n.º 22
0
static void
record(int skt)
{
    char	mode[] = { RECORD };

    max_fd     = skt;
    FD_ZERO(&open_fds);
    FD_SET(skt, &open_fds);

    while (1) {
	int    fd, nfds;
	fd_set    read_fds = open_fds, error_fds = open_fds;
	char    buf[MAX_CONCUR_MSG];

	if (0 > (nfds = select(max_fd+1, &read_fds, NULL, &error_fds, 0))) {
	    if (errno == EINTR)
		continue;
	    fprintf(stderr, "# concurs: select failed: %s\n", strerror(errno));
	    exit(1);
	}

	if (FD_ISSET(skt, &read_fds)) {
	    --nfds;
	    fd = sock_accept(skt);

	    if (0 >= sock_recv(fd, buf, sizeof buf)) {
		fprintf(stderr, "concurs: recv new player failed: %s\n", strerror(errno));
	    } else {
		sock_send(fd, mode, sizeof(mode));
		playerv[fd] = strdup(buf);
		printf("%s:%s\n", buf, buf);
		FD_SET(fd, &open_fds);
		if (max_fd < fd) max_fd = fd;
	    }
	}

	for (fd = skt+1; nfds > 0; ++fd) {
	    int    endit = 0, ret;

	    if (FD_ISSET(fd, &read_fds)) {
		--nfds;
		ret = sock_recv(fd, buf, sizeof(buf));
		if (ret < 0)
		    fprintf(stderr, "concurs: error reading %s\n", playerv[fd]);
		if (ret > 0)
		    printf("%s:%.*s\n", playerv[fd], ret, buf);
		else    endit = 1;
	    }

	    if (FD_ISSET(fd, &error_fds)) {
		--nfds;
		endit = 1;
		fprintf(stderr, "concurs: error from %s\n", playerv[fd]);
	    }

	    if (endit) {
		close(fd);
		FD_CLR(fd, &open_fds);
		free(playerv[fd]);
		playerv[fd] = NULL;
		while (max_fd > skt && !playerv[max_fd])
		    --max_fd;
	    }
	}
    }
}
Ejemplo n.º 23
0
connection_t *
get_connection (sock_t *sock)
{
	int sockfd;
	socklen_t sin_len;
	connection_t *con;
	fd_set rfds;
	struct timeval tv;
	int i, maxport = 0;
	struct sockaddr_in *sin = (struct sockaddr_in *)nmalloc(sizeof(struct sockaddr_in));

	if (!sin)
	{
		write_log (LOG_DEFAULT, "WARNING: Weird stuff in get_connection. nmalloc returned NULL sin");
		return NULL;
	}

	/* setup sockaddr structure */
	sin_len = sizeof(struct sockaddr_in);
	memset(sin, 0, sin_len);
  
	/* try to accept a connection */
	FD_ZERO(&rfds);
	
	for (i = 0; i < MAXLISTEN; i++) {
		if (sock_valid (sock[i])) {
			FD_SET(sock[i], &rfds);
			if (sock[i] > maxport) 
				maxport = sock[i];
		}
	}
	maxport += 1;

	tv.tv_sec = 0;
	tv.tv_usec = 30000;

	if (select(maxport, &rfds, NULL, NULL, &tv) > 0) {
		for (i = 0; i < MAXLISTEN; i++) {
			if (sock_valid (sock[i]) && FD_ISSET(sock[i], &rfds)) 
				break;
		}
	} else {
		nfree(sin);
		return NULL;
	}
	
	sockfd = sock_accept(sock[i], (struct sockaddr *)sin, &sin_len);
  
	if (sockfd >= 0) {
		con = create_connection();
		if (!sin)
		{
			xa_debug (1, "ERROR: NULL sockaddr struct, wft???");
			return NULL;
		}

		con->host = create_malloced_ascii_host(&(sin->sin_addr));
		con->sock = sockfd;
		con->sin = sin;
		con->sinlen = sin_len;
		xa_debug (2, "DEBUG: Getting new connection on socket %d from host %s", sockfd, con->host ? con->host : "(null)");
		con->hostname = NULL;
		con->headervars = NULL;
		con->id = new_id ();
		con->connect_time = get_time ();
#ifdef HAVE_LIBWRAP
		if (!sock_check_libwrap(sockfd, unknown_connection_e))
		{
			kick_not_connected (con, "Access Denied (tcp wrappers) [generic connection]");
			return NULL;
		}
#endif

		return con;
	}

	if (!is_recoverable (errno))
		xa_debug (1, "WARNING: accept() failed with on socket %d, max: %d, [%d:%s]", sock[i], maxport, 
			  errno, strerror(errno));
	nfree (sin);
	return NULL;
}
void *doControlConnection(void *parameters)
{
	int AddressFamily = AF_INET; //use IPv4
	int TransportProtocol = SOCK_STREAM; //use TCP

	char ErrBuf[1024];
	char DataBuffer[1024];
	int ChildSocket;				// keeps the socket ID for connections from clients
	struct addrinfo Hints;			// temporary struct to keep settings needed to open the new socket
	struct addrinfo *AddrInfo;		// keeps the addrinfo chain; required to open a new socket
	struct sockaddr_storage From;	// temp variable that keeps the parameters of the incoming connection
	int ReadBytes, WrittenBytes;
	int ServerSocket;

	// Prepare to open a new server socket
	memset(&Hints, 0, sizeof(struct addrinfo));

	Hints.ai_family= AddressFamily;
	Hints.ai_socktype= TransportProtocol;	// Open a TCP/UDP connection
	Hints.ai_flags = AI_PASSIVE;			// This is a server: ready to bind() a socket
	
	if (sock_initaddress (NULL, nf_params.tcp_port, &Hints, &AddrInfo, ErrBuf, sizeof(ErrBuf)) == sockFAILURE)
	{
		fprintf(logFile,"%s Error resolving given port (%s): %s\n",module_name, nf_params.tcp_port,ErrBuf);
		exit(EXIT_FAILURE);
	}

	if ( (ServerSocket= sock_open(AddrInfo, 1, 10,  ErrBuf, sizeof(ErrBuf))) == sockFAILURE)
	{
		// AddrInfo is no longer required
		sock_freeaddrinfo(AddrInfo);
		fprintf(logFile,"%s Cannot opening the socket: %s\n",module_name, ErrBuf);
		exit(EXIT_FAILURE);
	}

	// AddrInfo is no longer required
	sock_freeaddrinfo(AddrInfo);

	while(1)
	{
		if ( (ChildSocket= sock_accept(ServerSocket, &From, ErrBuf, sizeof(ErrBuf))) == sockFAILURE)
		{
			fprintf(logFile,"%s Error when accepting a new connection: %s\n",module_name, ErrBuf);
			exit(EXIT_FAILURE);
		}

		ReadBytes= sock_recv(ChildSocket, DataBuffer, sizeof(DataBuffer), SOCK_RECEIVEALL_NO, 0/*no timeout*/, ErrBuf, sizeof(ErrBuf));
		if (ReadBytes == sockFAILURE)
		{
			fprintf(logFile,"%s Error reading data: %s\n",module_name, ErrBuf);
			exit(EXIT_FAILURE);
		}

		// Terminate buffer, just for printing purposes
		// Warning: this can originate a buffer overflow
		DataBuffer[ReadBytes]= 0;

		fprintf(logFile,"%sData received (%d bytes):\n",module_name, ReadBytes);
		fprintf(logFile,"%s %s\n",module_name,DataBuffer);

		char answer[1024];
		sprintf(answer,"Greeting from network function\"%s\"",nf_params.nf_name);
		
		fprintf(logFile,"%s Answer to be sent: %s\n",module_name,answer);
		WrittenBytes= sock_send(ChildSocket, answer, strlen(answer), ErrBuf, sizeof(ErrBuf));
		if (WrittenBytes == sockFAILURE)
		{
			fprintf(logFile,"%s Error sending data: %s",module_name, ErrBuf);
			exit(EXIT_FAILURE);

		}

		sock_close(ChildSocket,ErrBuf,sizeof(ErrBuf));
	}
}
Ejemplo n.º 25
0
static int ftp_send(const char *path, FILE *fp, putmode_t how,
					transfer_mode_t mode, ftp_transfer_func hookf)
{
	int r;
	long rp = ftp->restart_offset;
	ftp->restart_offset = 0L;

	if(how == putUnique && !ftp->has_stou_command)
		return -1;

  if (how == putTryUnique && !ftp->has_stou_command)
    how = putNormal;

	reset_transfer_info();
	ftp->ti.transfer_is_put = true;

	if(ftp_init_transfer() != 0)
		return -1;

	ftp_type(mode);

	if(rp > 0) {
		/* fp is assumed to be fseek'd already */
		ftp_cmd("REST %ld", rp);
		if(ftp->code != ctContinue)
			return -1;
		ftp->ti.size = rp;
		ftp->ti.restart_size = rp;
	}

  ftp_set_tmp_verbosity(vbError);
  switch (how) {
  case putAppend:
    ftp_cmd("APPE %s", path);
    break;

  case putTryUnique:
  case putUnique:
    ftp_cmd("STOU %s", path);
    if (ftp->fullcode == 502 || ftp->fullcode == 504) {
      ftp->has_stou_command = false;
      if (how == putTryUnique)
        how = putNormal;
      else
        break;
    }
    else
      break;

  default:
    ftp_cmd("STOR %s", path);
    break;
  }

	if(ftp->code != ctPrelim)
		return -1;

	if(how == putUnique) {
		/* try to figure out remote filename */
		char *e = strstr(ftp->reply, " for ");
		if(e) {
			int l;
			e += 5;
			l = strlen(e);
			if(l) {
				free(ftp->ti.local_name);
				if(*e == '\'')
					ftp->ti.local_name = xstrndup(e+1, l-3);
				else
					ftp->ti.local_name = xstrndup(e, l-1);
				ftp_trace("parsed unique filename as '%s'\n",
						  ftp->ti.local_name);
			}
		}
	}

	if(!sock_accept(ftp->data, "w", ftp_is_passive())) {
		ftp_err(_("data connection not accepted\n"));
		return -1;
	}

	ftp_cache_flush_mark_for(path);

	if(mode == tmBinary)
		r = FILE_send_binary(fp, ftp->data);
	else
		r = FILE_send_ascii(fp, ftp->data);
	sock_flush(ftp->data);
	sock_destroy(ftp->data);
	ftp->data = 0;

	if(r == 0) {
		transfer_finished();
		ftp_read_reply();
		ftp->ti.ioerror = (ftp->code != ctComplete);
		if(ftp->code != ctComplete) {
			ftp_trace("transfer failed\n");
			return -1;
		}
	} else
		transfer_finished();

	return 0;
}
Ejemplo n.º 26
0
static void
play(int skt, const char *file, int timeout)
{
    char	mode[] = { PLAY };
    char	*cp;
    char	expect[MAX_CONCUR_NAME+1+MAX_CONCUR_MSG];
    char	actual[MAX_CONCUR_MSG];
    MAP	conh = map_create((map_diff*)strcmp, (map_hash*)fnv04, NULL);
    FILE	*fp = fopen(file, "r");
    fd_set	fds;

    if (!fp) {
	fprintf(stderr, "error: cannot read %s\n", file);
	exit(2);
    }

    FD_ZERO(&fds);

    while (fgets(expect, sizeof expect, fp)) {
	int	fd, ret;
	struct timeval    to = { timeout, 0 };

	for (cp = expect + strlen(expect); cp > expect && isspace(cp[-1]); *--cp = 0);

	if (!expect[0])
	    continue;

	if (expect[0] == '#') {
	    if (expect[1] != ':') 
		fputs(expect, stdout);
	    continue;
	}

	if (!(cp = strchr(expect, ':'))) {
	    fprintf(stderr, "concurs: invalid script line:\n%s\n", expect);
	    continue;
	}
	*cp++ = 0;

	while (!(fd = (int)(uintptr_t)map_get(conh, expect))) {
	    FD_SET(skt, &fds);
	    if (timeout && 0 > select(skt+1, &fds, NULL, NULL, &to)) {
		fprintf(stderr, "concurs: timed out waiting for %s:connect\n", expect);
		exit(1);
	    }
	    FD_CLR(skt, &fds);
		
	    fd = sock_accept(skt);
	    FD_SET(fd, &open_fds);
	    cp = playerv[fd] = strdup(expect);
	    map_set(conh, playerv[fd], (void*)(uintptr_t)fd);
	}

	FD_SET(fd, &fds);
	if (timeout && 0 > select(skt+1, &fds, NULL, NULL, &to)) {
	    fprintf(stderr, "concurs: error waiting for %s:%s\n", expect, cp);
	    exit(1);
	}
	FD_CLR(fd, &fds);

	if (0 >= (ret = sock_recv(fd, actual, sizeof actual))) {
	    close(fd);
	    FD_CLR(fd, &open_fds);
	    map_del(conh, playerv[fd]);
	    free(playerv[fd]);
	    playerv[fd] = NULL;
	}

	sock_send(fd, mode, sizeof(mode));
	//REVISIT: select(nowait) on all open fds and report who was blocked.
	printf("%s:%s\n", expect, actual);
	if (strcmp(cp, actual)) {
	    fprintf(stderr, "concurs: broken\n");
	    exit(1);
	}
    }
}
Ejemplo n.º 27
0
int udpclient(int argc, char *argv[])
{

	list_t *clients = NULL;
	list_t *conn_clients;
	client_t *client;
	client_t *tunnel;
	client_t *client2;

	char data[MSG_MAX_LEN];
	char addrstr[ADDRSTRLEN];
	char taddrstr[ADDRSTRLEN];

	socket_t *tcp_sock = NULL;
	socket_t *udp_sock = NULL;
	socket_t *next_sock = NULL;

	struct timeval curr_time;
	struct timeval check_time;
	struct timeval check_interval;
	struct timeval timeout;
	fd_set client_fds;
	fd_set read_fds;
	uint16_t tmp_id;
	uint8_t tmp_type;
	uint16_t tmp_len;
	// uint16_t tmp_req_id;
	int num_fds;
	uint32_t sourceid;



	int ret;
	int i;

	signal(SIGINT, &signal_handler);

	i = 0;    
	lhost = (argc - i == 5) ? NULL : argv[i++];
	lport = argv[i++];
	rport = argv[i++];
	phost = argv[i++];
	pport = argv[i++];
	relays = atoi(argv[i++]);
	if(debug_level >= DEBUG_LEVEL1)
		printf("relays need %d \n",relays);


	/* Check validity of ports (can't check ip's b/c might be host names) */

	ERROR_GOTO(!isnum(lport), "Invalid listen port.", done);

	ERROR_GOTO(!isnum(rport), "Invalid recv port.", done);

	ERROR_GOTO(!isnum(pport), "Invalid inter port.", done);
	//ERROR_GOTO(!isnum(rport), "Invalid remote port.", done);

	srand(inet_addr(lhost));
	localid=(rand());
	generate_rsakey(lhost);
	if(debug_level >= DEBUG_LEVEL1)
	{
		printf("local id %d \n",localid);
	}
	next_req_id = rand() % 0xffff;

	/* Create an empty list for the clients */
	clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
	                      p_client_free, 1);
	ERROR_GOTO(clients == NULL, "Error creating clients list.", done);

	/* Create and empty list for the connecting clients */
	conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
	                           p_client_free, 1);
	ERROR_GOTO(conn_clients == NULL, "Error creating conn_clients list.", done);

	relay_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy,
	                            p_client_free, 1);
	ERROR_GOTO(relay_clients == NULL, "Error creating clients list.", done);

	/* Create a TCP server socket to listen for incoming connections */
	tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1);

	ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done);
	udp_serv = sock_create(lhost, rport,ipver, SOCK_TYPE_UDP, 1, 1);
	ERROR_GOTO(udp_serv == NULL, "Error creating TCP socket.", done);
	if(debug_level >= DEBUG_LEVEL1)
	{
		printf("Listening on TCP %s,UDP %s \n",
		       sock_get_str(tcp_serv, addrstr, sizeof(addrstr)),sock_get_str(udp_serv, taddrstr, sizeof(taddrstr)));
	}
	next_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1);

	msg_send_req(next_sock,lhost,rport,0,localid);	   
	sock_free(next_sock);		
	next_sock = NULL;		

	FD_ZERO(&client_fds);

	/* Initialize all the timers */
	timerclear(&timeout);
	check_interval.tv_sec = 0;
	check_interval.tv_usec = 500000;
	gettimeofday(&check_time, NULL);


	while(running)
	{
		if(!timerisset(&timeout))
			timeout.tv_usec = 50000;

		read_fds = client_fds;
		FD_SET(SOCK_FD(tcp_serv), &read_fds);
		FD_SET(SOCK_FD(udp_serv), &read_fds);

		ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
		PERROR_GOTO(ret < 0, "select", done);
		num_fds = ret;

		gettimeofday(&curr_time, NULL);

		/* Go through all the clients and check if didn't get an ACK for sent
		 data during the timeout period */
		if(timercmp(&curr_time, &check_time, >))
		{
			for(i = 0; i < LIST_LEN(clients); i++)
			{
				client = list_get_at(clients, i);

				ret = client_check_and_resend(client, curr_time);
				if(ret == -2)
				{
					disconnect_and_remove_client(CLIENT_ID(client), clients,
					                             &client_fds, 1);
					i--;
					continue;
				}

				ret = client_check_and_send_keepalive(client, curr_time);
				if(ret == -2)
				{
					disconnect_and_remove_client(CLIENT_ID(client), clients,
					                             &client_fds, 1);
					i--;
				}
			}

			timeradd(&curr_time, &check_interval, &check_time);
		}

		if(num_fds == 0)
			continue;

		/* Check if pending TCP connection to accept and create a new client
		 and UDP connection if one is ready */
		if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds))
		{
			tcp_sock = sock_accept(tcp_serv);
			if(tcp_sock == NULL)
				continue;
			if(SelectMethod(tcp_sock->fd)==-1)
			{ 
				if(debug_level >= DEBUG_LEVEL1)
					printf("socks version error\n");
				return-1;
			}
			rhost=ParseCommand(tcp_sock->fd);
			if (0<LIST_LEN(relay_clients))
			{

				tunnel = list_get_at(relay_clients, 0);

				udp_sock =sock_copy(CLIENT_TCP_SOCK(tunnel));

				SOCK_FD(udp_sock)=socket(AF_INET, SOCK_DGRAM, 0); 					
			}

			if(udp_sock == NULL)
			{
				sock_close(tcp_sock);
				sock_free(tcp_sock);
				continue;
			}

			client = client_create(next_req_id++, localid, tcp_sock, udp_sock, 1);
			memcpy(client->rsakey,tunnel->rsakey,strlen(tunnel->rsakey));

			printf("expid rsakey is %s",client->rsakey);
			if(debug_level >= DEBUG_LEVEL1)
				printf("create client id %d \n",CLIENT_ID(client));
			if(!client || !tcp_sock || !udp_sock)
			{
				if(tcp_sock)
					sock_close(tcp_sock);
				if(udp_sock)
					sock_close(udp_sock);
			}
			else
			{
				client2 = list_add(conn_clients, client, 1);
				client_free(client);
				client = NULL;
				if(debug_level >= DEBUG_LEVEL1)
				{
					sock_get_str(CLIENT_TCP_SOCK(client2), addrstr,
					             sizeof(addrstr));				
					printf("tunnel(%d): local %s ",client2->sourceid, addrstr);
					sock_get_str(CLIENT_UDP_SOCK(client2), addrstr,
					             sizeof(addrstr));
					printf("to %s \n",addrstr);
				}
				client_send_hello(client2,rhost,CLIENT_ID(client2));
				client_add_tcp_fd_to_set(client2, &client_fds);
				//client_add_udp_fd_to_set(client2, &client_fds);
			}

			sock_free(tcp_sock);
			sock_free(udp_sock);
			tcp_sock = NULL;
			udp_sock = NULL;

			num_fds--;
		}

		/* Check for UDP data */
		if(FD_ISSET(SOCK_FD(udp_serv), &read_fds))
		{


			//ret = client_recv_udp_msg(client, data, sizeof(data),
			//                          &tmp_id, &tmp_type, &tmp_len,&sourceid);
			ret = msg_recv_msg(udp_serv, data, sizeof(data),
			                   &tmp_id, &tmp_type, &tmp_len,&sourceid);

			if(debug_level >= DEBUG_LEVEL2)
				printf("recv msg from %d type %d %d bytes \n ",sourceid,tmp_type,tmp_len);
			if(ret == 0)
				ret = handle_message(tmp_id, tmp_type,
				                     data, tmp_len,sourceid,clients, conn_clients);
			/*if(ret < 0)
			{

				disconnect_and_remove_client(tmp_id, clients,
				                             &client_fds, 1);

		}	*/		
		}

		/* Check if data is ready from any of the clients */
		for(i = 0; i < LIST_LEN(clients); i++)
		{
			client = list_get_at(clients, i);



			/* Check for TCP data */
			if(num_fds > 0 && client_tcp_fd_isset(client, &read_fds))
			{
				ret = client_recv_tcp_data(client);
				if(ret == -1)
				{
					disconnect_and_remove_client(CLIENT_ID(client), clients,
					                             &client_fds, 1);
					i--;
					continue;
				}
				else if(ret == -2)
				{
					client_mark_to_disconnect(client);
					disconnect_and_remove_client(CLIENT_ID(client),
					                             clients, &client_fds, 0);
				}

				num_fds--;
			}

			/* send any TCP data that was ready */
			ret = client_send_udp_data(client);
			if(ret < 0)
			{
				disconnect_and_remove_client(CLIENT_ID(client), clients,
				                             &client_fds, 1);
				i--;
			}
		}

		/* Finally, send any udp data that's still in the queue */
		for(i = 0; i < LIST_LEN(clients); i++)
		{
			client = list_get_at(clients, i);
			ret = client_send_udp_data(client);

			if(ret < 0 || client_ready_to_disconnect(client))
			{
				disconnect_and_remove_client(CLIENT_ID(client), clients,
				                             &client_fds, 1);
				i--;
			}
		}
	}

	done:
		if(debug_level >= DEBUG_LEVEL1)
			printf("Cleaning up...\n");
		if(tcp_serv)
	{
		sock_close(tcp_serv);
		sock_free(tcp_serv);
	}
		if(udp_serv)
	{
		sock_close(udp_serv);
		sock_free(udp_serv);
	}
		if(clients)
			list_free(clients);
		if(conn_clients)
			list_free(conn_clients);
		if(debug_level >= DEBUG_LEVEL1)
			printf("Goodbye.\n");
		return 0;
}
Ejemplo n.º 28
0
void listen_loop(int do_init) {
	struct client_struct* new_client;
	struct np_sock npsock = {.count = 0};
	int ret;
	struct timespec ts;
#ifdef NP_SSH
	ssh_bind sshbind = NULL;
#endif
#ifdef NP_TLS
	SSL_CTX* tlsctx = NULL;
#endif

	/* Init */
	if (do_init) {
#ifdef NP_SSH
		np_ssh_init();
#endif
#ifdef NP_TLS
		np_tls_init();
#endif
		if ((ret = pthread_create(&netopeer_state.data_tid, NULL, data_thread, NULL)) != 0) {
			nc_verb_error("%s: failed to create a thread (%s)", __func__, strerror(ret));
			return;
		}
		if ((ret = pthread_create(&netopeer_state.netconf_rpc_tid, NULL, netconf_rpc_thread, NULL)) != 0) {
			nc_verb_error("%s: failed to create a thread (%s)", __func__, strerror(ret));
			return;
		}
	}

	/* Main accept loop */
	do {
		new_client = NULL;

		/* Binds change check */
		if (netopeer_options.binds_change_flag) {
			/* BINDS LOCK */
			pthread_mutex_lock(&netopeer_options.binds_lock);

			sock_cleanup(&npsock);
			sock_listen(netopeer_options.binds, &npsock);

			netopeer_options.binds_change_flag = 0;
			/* BINDS UNLOCK */
			pthread_mutex_unlock(&netopeer_options.binds_lock);

			if (npsock.count == 0) {
				nc_verb_warning("Server is not listening on any address!");
			}
		}

#ifdef NP_SSH
		sshbind = np_ssh_server_id_check(sshbind);
#endif
#ifdef NP_TLS
		tlsctx = np_tls_server_id_check(tlsctx);
#endif

#ifndef DISABLE_CALLHOME
		/* Callhome client check */
		if (callhome_client != NULL) {
			/* CALLHOME LOCK */
			pthread_mutex_lock(&callhome_lock);
			new_client = callhome_client;
			callhome_client = NULL;
			/* CALLHOME UNLOCK */
			pthread_mutex_unlock(&callhome_lock);
		}
#endif

		/* Listen client check */
		if (new_client == NULL) {
			new_client = sock_accept(&npsock);
		}

		/* New client full structure creation */
		if (new_client != NULL) {

			/* Maximum number of sessions check */
			if (netopeer_options.max_sessions > 0) {
				ret = 0;
#ifdef NP_SSH
				ret += np_ssh_session_count();
#endif
#ifdef NP_TLS
				ret += np_tls_session_count();
#endif

				if (ret >= netopeer_options.max_sessions) {
					nc_verb_error("Maximum number of sessions reached, droppping the new client.");
					new_client->to_free = 1;
					switch (new_client->transport) {
#ifdef NP_SSH
					case NC_TRANSPORT_SSH:
						client_free_ssh((struct client_struct_ssh*)new_client);
						break;
#endif
#ifdef NP_TLS
					case NC_TRANSPORT_TLS:
						client_free_tls((struct client_struct_tls*)new_client);
						break;
#endif
					default:
						nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__);
					}
					free(new_client);

					/* sleep to prevent clients from immediate connection retry */
					usleep(netopeer_options.response_time*1000);
					continue;
				}
			}

			switch (new_client->transport) {
#ifdef NP_SSH
			case NC_TRANSPORT_SSH:
				ret = np_ssh_create_client((struct client_struct_ssh*)new_client, sshbind);
				if (ret != 0) {
					new_client->to_free = 1;
					client_free_ssh((struct client_struct_ssh*)new_client);
				}
				break;
#endif
#ifdef NP_TLS
			case NC_TRANSPORT_TLS:
				ret = np_tls_create_client((struct client_struct_tls*)new_client, tlsctx);
				if (ret != 0) {
					new_client->to_free = 1;
					client_free_tls((struct client_struct_tls*)new_client);
				}
				break;
#endif
			default:
				nc_verb_error("Client with an unknown transport protocol, dropping it.");
				new_client->to_free = 1;
				ret = 1;
			}

			/* client is not valid, some error occured */
			if (ret != 0) {
				free(new_client);
				continue;
			}

			/* add the client into the global clients structure */
			/* GLOBAL WRITE LOCK */
			pthread_rwlock_wrlock(&netopeer_state.global_lock);
			client_append(&netopeer_state.clients, new_client);
			/* GLOBAL WRITE UNLOCK */
			pthread_rwlock_unlock(&netopeer_state.global_lock);
		}

	} while (!quit && !restart_soft);

	/* Cleanup */
	sock_cleanup(&npsock);
#ifdef NP_SSH
	ssh_bind_free(sshbind);
#endif
#ifdef NP_TLS
	SSL_CTX_free(tlsctx);
#endif
	if (!restart_soft) {
		if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
			nc_verb_warning("%s: failed to get time (%s)", strerror(errno));
		}
		ts.tv_sec += THREAD_JOIN_QUIT_TIMEOUT;

		/* wait for all the clients to exit nicely themselves */
		if ((ret = pthread_timedjoin_np(netopeer_state.netconf_rpc_tid, NULL, &ts)) != 0) {
			nc_verb_warning("%s: failed to join the netconf RPC thread (%s)", __func__, strerror(ret));
			if (ret == ETIMEDOUT) {
				pthread_cancel(netopeer_state.netconf_rpc_tid);
			}
		}
		if ((ret = pthread_timedjoin_np(netopeer_state.data_tid, NULL, &ts)) != 0) {
			nc_verb_warning("%s: failed to join the SSH data thread (%s)", __func__, strerror(ret));
			if (ret == ETIMEDOUT) {
				pthread_cancel(netopeer_state.data_tid);
			}
		}

#ifdef NP_SSH
		np_ssh_cleanup();
#endif
#ifdef NP_TLS
		np_tls_cleanup();
#endif
	}
}

int main(int argc, char** argv) {
	struct sigaction action;
	sigset_t block_mask;

	char *aux_string = NULL, path[PATH_MAX];
	int next_option;
	int daemonize = 0, len;
	int listen_init = 1;
	struct np_module* netopeer_module = NULL, *server_module = NULL;

	/* initialize message system and set verbose and debug variables */
	if ((aux_string = getenv(ENVIRONMENT_VERBOSE)) == NULL) {
		netopeer_options.verbose = NC_VERB_ERROR;
	} else {
		netopeer_options.verbose = atoi(aux_string);
	}

	aux_string = NULL; /* for sure to avoid unwanted changes in environment */

	/* parse given options */
	while ((next_option = getopt(argc, argv, OPTSTRING)) != -1) {
		switch (next_option) {
		case 'd':
			daemonize = 1;
			break;
		case 'h':
			print_usage(argv[0]);
			break;
		case 'v':
			netopeer_options.verbose = atoi(optarg);
			break;
		case 'V':
			print_version(argv[0]);
			break;
		default:
			print_usage(argv[0]);
			break;
		}
	}

	/* set signal handler */
	sigfillset (&block_mask);
	action.sa_handler = signal_handler;
	action.sa_mask = block_mask;
	action.sa_flags = 0;
	sigaction(SIGINT, &action, NULL);
	sigaction(SIGQUIT, &action, NULL);
	sigaction(SIGABRT, &action, NULL);
	sigaction(SIGTERM, &action, NULL);
	sigaction(SIGHUP, &action, NULL);

	nc_callback_print(clb_print);

	/* normalize value if not from the enum */
	if (netopeer_options.verbose > NC_VERB_DEBUG) {
		netopeer_options.verbose = NC_VERB_DEBUG;
	}
	nc_verbosity(netopeer_options.verbose);

	/* go to the background as a daemon */
	if (daemonize == 1) {
		if (daemon(0, 0) != 0) {
			nc_verb_error("Going to background failed (%s)", strerror(errno));
			return EXIT_FAILURE;
		}
		openlog("netopeer-server", LOG_PID, LOG_DAEMON);
	} else {
		openlog("netopeer-server", LOG_PID|LOG_PERROR, LOG_DAEMON);
	}

	/* make sure we were executed by root */
	if (geteuid() != 0) {
		nc_verb_error("Failed to start, must have root privileges.");
		return EXIT_FAILURE;
	}

	/*
	 * this initialize the library and check potential ABI mismatches
	 * between the version it was compiled for and the actual shared
	 * library used.
	 */
	LIBXML_TEST_VERSION

	/* initialize library including internal datastores and maybee something more */
	if (nc_init(NC_INIT_ALL | NC_INIT_MULTILAYER) < 0) {
		nc_verb_error("Library initialization failed.");
		return EXIT_FAILURE;
	}

	server_start = 1;

restart:
	/* start NETCONF server module */
	if ((server_module = calloc(1, sizeof(struct np_module))) == NULL) {
		nc_verb_error("Creating necessary NETCONF server plugin failed!");
		return EXIT_FAILURE;
	}
	server_module->name = strdup(NCSERVER_MODULE_NAME);
	if (module_enable(server_module, 0)) {
		nc_verb_error("Starting necessary NETCONF server plugin failed!");
		free(server_module->name);
		free(server_module);
		return EXIT_FAILURE;
	}

	/* start netopeer device module - it will start all modules that are
	 * in its configuration and in server configuration */
	if ((netopeer_module = calloc(1, sizeof(struct np_module))) == NULL) {
		nc_verb_error("Creating necessary Netopeer plugin failed!");
		module_disable(server_module, 1);
		return EXIT_FAILURE;
	}
	netopeer_module->name = strdup(NETOPEER_MODULE_NAME);
	if (module_enable(netopeer_module, 0)) {
		nc_verb_error("Starting necessary Netopeer plugin failed!");
		module_disable(server_module, 1);
		free(netopeer_module->name);
		free(netopeer_module);
		return EXIT_FAILURE;
	}

	server_start = 0;
	nc_verb_verbose("Netopeer server successfully initialized.");

	listen_loop(listen_init);

	/* unload Netopeer module -> unload all modules */
	module_disable(server_module, 1);
	module_disable(netopeer_module, 1);

	/* main cleanup */

	if (!restart_soft) {
		/* close libnetconf only when shutting down or hard restarting the server */
		nc_close();
	}

	if (restart_soft) {
		nc_verb_verbose("Server is going to soft restart.");
		restart_soft = 0;
		listen_init = 0;
		goto restart;
	} else if (restart_hard) {
		nc_verb_verbose("Server is going to hard restart.");
		len = readlink("/proc/self/exe", path, PATH_MAX);
		path[len] = 0;
		xmlCleanupParser();
		execv(path, argv);
	}

	/*
	 *Free the global variables that may
	 *have been allocated by the parser.
	 */
	xmlCleanupParser();

	return EXIT_SUCCESS;
}
Ejemplo n.º 29
0
/*
 *  Thread to control the acquisition of data, allows only 1 connection at a time
 */
void control_thread (void * arg) 
{

  udpdb_t * ctx = (udpdb_t *) arg;

  if (ctx->verbose)
    multilog(ctx->log, LOG_INFO, "control_thread: starting\n");

  // port on which to listen for control commands
  int port = ctx->control_port;

  // buffer for incoming command strings
  int bufsize = 1024;
  char* buffer = (char *) malloc (sizeof(char) * bufsize);
  assert (buffer != 0);

  const char* whitespace = " \r\t\n";
  char * command = 0;
  char * args = 0;
  //time_t utc_start = 0;

  FILE *sockin = 0;
  FILE *sockout = 0;
  int listen_fd = 0;
  int fd = 0;
  char *rgot = 0;
  int readsocks = 0;
  fd_set socks;
  struct timeval timeout;

  // create a socket on which to listen
  if (ctx->verbose)
    multilog(ctx->log, LOG_INFO, "control_thread: creating socket on port %d\n", port);

  listen_fd = sock_create (&port);
  if (listen_fd < 0)  {
    multilog(ctx->log, LOG_ERR, "Failed to create socket for control commands: %s\n", strerror(errno));
    free (buffer);
    return;
  }

  while (!quit_threads) {

    // reset the FD set for selecting  
    FD_ZERO(&socks);
    FD_SET(listen_fd, &socks);
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    readsocks = select(listen_fd+1, &socks, (fd_set *) 0, (fd_set *) 0, &timeout);

    // error on select
    if (readsocks < 0) 
    {
      perror("select");
      exit(EXIT_FAILURE);
    }

    // no connections, just ignore
    else if (readsocks == 0) 
    {
    } 

    // accept the connection  
    else 
    {
   
      if (ctx->verbose) 
        multilog(ctx->log, LOG_INFO, "control_thread: accepting conection\n");

      fd =  sock_accept (listen_fd);
      if (fd < 0)  {
        multilog(ctx->log, LOG_WARNING, "control_thread: Error accepting "
                                        "connection %s\n", strerror(errno));
        break;
      }

      sockin = fdopen(fd,"r");
      if (!sockin)
        multilog(ctx->log, LOG_WARNING, "control_thread: error creating input "
                                        "stream %s\n", strerror(errno));


      sockout = fdopen(fd,"w");
      if (!sockout)
        multilog(ctx->log, LOG_WARNING, "control_thread: error creating output "
                                        "stream %s\n", strerror(errno));

      setbuf (sockin, 0);
      setbuf (sockout, 0);

      rgot = fgets (buffer, bufsize, sockin);

      //if (rgot && !feof(sockin)) {
      while (rgot && !feof(sockin)) {

        buffer[strlen(buffer)-2] = '\0';

        args = buffer;

        // parse the command and arguements
        command = strsep (&args, whitespace);

        if (ctx->verbose)
        {
          multilog(ctx->log, LOG_INFO, "control_thread: command=%s\n", command);
          if (args != NULL)
            multilog(ctx->log, LOG_INFO, "control_thread: args=%s\n", args);
        }

        // REQUEST STATISTICS
        if (strcmp(command, "STATS") == 0) 
        {
          fprintf (sockout, "mb_rcv_ps=%4.1f,mb_drp_ps=%4.1f,"
                            "ooo_pkts=%"PRIu64",mb_free=%4.1f,mb_total=%4.1f\r\n", 
                             ctx->mb_rcv_ps, ctx->mb_drp_ps, 
                             ctx->ooo_packets, ctx->mb_free, ctx->mb_total);
          fprintf (sockout, "ok\r\n");
        }

        else if (strcmp(command, "SET_UTC_START") == 0)
        {
          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: SET_UTC_START command received\n");
          if (args == NULL)
          {
            multilog(ctx->log, LOG_ERR, "control_thread: no time specified for SET_UTC_START\n");
            fprintf(sockout, "fail\r\n");
          }
          else
          {
            time_t utc = str2utctime (args);
            if (utc == (time_t)-1)
            {
              multilog(ctx->log, LOG_WARNING, "control_thread: could not parse "
                       "UTC_START time from %s\n", args);
              fprintf(sockout, "fail\r\n");
            }
            else
            {
              if (ctx->verbose)
                multilog(ctx->log, LOG_INFO, "control_thread: parsed UTC_START as %d\n", utc);

	      // set global utc_start to parsed value, used when START command arrives
              utc_start = utc;
              fprintf(sockout, "ok\r\n");
              multilog(ctx->log, LOG_INFO, "set_utc_start %s\n", args);
            }
          }
        }

        // START COMMAND
        else if (strcmp(command, "START") == 0) {

          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: START command received\n");

          start_pending = 1;
          while (recording != 1) 
          {
            //sleep(1);
            usleep(100000);
          }
          start_pending = 0;
          fprintf(sockout, "ok\r\n");

          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: recording started\n");
        }

        // FLUSH COMMAND - stop acquisition of data, but flush all packets already received
        else if (strcmp(command, "FLUSH") == 0)
        {
          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: FLUSH command received, stopping recording\n");

          stop_pending = 1;
          while (recording != 0)
          {
            sleep(1);
          }
          stop_pending = 0;
          fprintf(sockout, "ok\r\n");

          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: recording stopped\n");
        }

        // UTC_STOP command
        else if (strcmp(command, "UTC_STOP") == 0)
        {
          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: UTC_STOP command received\n");

          if (args == NULL) 
          {
            multilog(ctx->log, LOG_ERR, "control_thread: no UTC specified for UTC_STOP\n");
            fprintf(sockout, "fail\r\n");
          }
          else
          {
            time_t utc = str2utctime (args);
            if (utc == (time_t)-1) 
            {
              multilog(ctx->log, LOG_WARNING, "control_thread: could not parse "
                       "UTC_STOP time from %s\n", args);
              fprintf(sockout, "fail\r\n");
            }
            else
            {
              if (ctx->verbose)
                multilog(ctx->log, LOG_INFO, "control_thread: parsed UTC_STOP as %d\n", utc); 
              uint64_t byte_to_stop = (utc - utc_start);
              byte_to_stop *= 800 * 1000 * 1000;
              if (ctx->verbose)
                multilog(ctx->log, LOG_INFO, "control_thread: total_secs=%d, "
                         "stopping byte=%"PRIu64"\n", (utc - utc_start), byte_to_stop);
              stop_byte = byte_to_stop;
              stop_pending = 0;
              utc_start = 0;
              fprintf(sockout, "ok\r\n");
              multilog(ctx->log, LOG_INFO, "utc_stop %s\n", args);
            }
          }
        }

        // STOP command, stops immediately
        else if (strcmp(command, "STOP") == 0)
        {
          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: STOP command received, stopping immediately\n");

          stop_pending = 2;
          stop_byte = (ctx->last_byte > 0) ? ctx->last_byte : 1;
          while (recording != 0)
          {
            sleep(1);
          }
          stop_pending = 0;
          fprintf(sockout, "ok\r\n");

          if (ctx->verbose)
            multilog(ctx->log, LOG_INFO, "control_thread: recording stopped\n");
        }


        // QUIT COMMAND, immediately exit 
        else if (strcmp(command, "QUIT") == 0) 
        {
          multilog(ctx->log, LOG_INFO, "control_thread: QUIT command received, exiting\n");
          quit_threads = 1;
          fprintf(sockout, "ok\r\n");
          close(fd);
          break;
        }

        // UNRECOGNISED COMMAND
        else 
        {
          multilog(ctx->log, LOG_WARNING, "control_thread: unrecognised command: %s\n", buffer);
          fprintf(sockout, "fail\r\n");
        }
        // try to read the next line of input
        rgot = fgets (buffer, bufsize, sockin);
      }
      close(fd);
    }

    //close(fd);
  }
  close(listen_fd);

  free (buffer);

  if (ctx->verbose)
    multilog(ctx->log, LOG_INFO, "control_thread: exiting\n");

}