Ejemplo n.º 1
0
int main(int argc, char **argv)
{
    time_seed = time(0);

    parse_parameters(argc, argv);

    if (getuid() == 0)
    {
        if (UID == -1)
            error("user not set");
        if (setgid(GID) != 0)
            error("Unable to drop group privileges");
        if (setuid(UID) != 0)
            error("Unable to drop user privileges");
    }

    if (BASEDIR == NULL)
        set_basedir();

    startup_message();

    int listen_socket, optval = 1;
    struct sockaddr_in server_address;

    listen_socket = create_socket();
    setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int));

    server_address = set_address(server_address);
    bind_to_port(listen_socket, server_address);

    if (DAEMON)
    {
        pid_t pid;

        pid = fork();
        if (pid == -1)
            error("Failed to fork");
        if (pid == 0)
            while (1) perform_connection(listen_socket);
    }
    else
        while (1) perform_connection(listen_socket);

    return 0;
}
Ejemplo n.º 2
0
int main(int argc, char **argv) {
    main_b();
    int listen_socket, connection_socket = 0, address_lenght, optval = 1;
    struct sockaddr_in server_address, client_address;
    listen_socket = create_socket();
    setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int));
    server_address = set_address(server_address);
    bind_to_port(listen_socket, server_address);
    address_lenght = sizeof(client_address);
    while (1) perform_connection(connection_socket, listen_socket, client_address, address_lenght);
}
Ejemplo n.º 3
0
int main(int argc, char **argv) {
#ifdef _WIN32
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,0), &wsaData);
#endif
    main_b();
    int listen_socket, connection_socket = 0, address_lenght, optval = 1;
    struct sockaddr_in server_address, client_address;
    listen_socket = create_socket();
    setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int));
    server_address = set_address(server_address);
    bind_to_port(listen_socket, server_address);
    address_lenght = sizeof(client_address);
    while (1) perform_connection(connection_socket, listen_socket, client_address, address_lenght);
}
Ejemplo n.º 4
0
int do_socketpair(message *dev_m_in, message *dev_m_out)
{
	int rc;
	dev_t minorin;
	int minorx, minory;
	struct sockaddr_un addr;

#if DEBUG == 1
	static int call_count = 0;
	printf("(uds) [%d] do_socketpair() call_count=%d\n",
				uds_minor(dev_m_in), ++call_count);
#endif

	/* first ioctl param is the first socket */
	minorx = uds_minor(dev_m_in);

	/* third ioctl param is the minor number of the second socket */
	rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT,
			(vir_bytes) 0, (vir_bytes) &minorin, sizeof(dev_t));

	if (rc != OK) {
		return EIO;
	}

	minory = minor(minorin);

#if DEBUG == 1
	printf("socketpair() %d - %d\n", minorx, minory);
#endif

	/* security check - both sockets must have the same endpoint (owner) */
	if (uds_fd_table[minorx].owner != uds_fd_table[minory].owner) {

		/* we won't allow you to magically connect your socket to
		 * someone elses socket
		 */
		return EPERM;
	}

	addr.sun_family = AF_UNIX;
	addr.sun_path[0] = 'X';
	addr.sun_path[1] = '\0';

	uds_fd_table[minorx].syscall_done = 1;
	return perform_connection(dev_m_in, dev_m_out, &addr, minorx, minory);
}
Ejemplo n.º 5
0
int do_connect(message *dev_m_in, message *dev_m_out)
{
	int minor, child;
	struct sockaddr_un addr;
	int rc, i, j;

#if DEBUG == 1
	static int call_count = 0;
	printf("(uds) [%d] do_connect() call_count=%d\n", uds_minor(dev_m_in),
								++call_count);
#endif

	minor = uds_minor(dev_m_in);

	/* only connection oriented sockets can connect */
	if (uds_fd_table[minor].type != SOCK_STREAM &&
			uds_fd_table[minor].type != SOCK_SEQPACKET) {
		return EINVAL;
	}

	if (uds_fd_table[minor].peer != -1) {
		/* socket is already connected */
		return EISCONN;
	}

	rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT,
				(vir_bytes) 0, (vir_bytes) &addr,
				sizeof(struct sockaddr_un));

	if (rc != OK) {
		return EIO;
	}

	rc = check_perms(minor, &addr);
	if (rc != OK) {
		/* permission denied, socket file doesn't exist, etc. */
		return rc;
	}

	/* look for a socket of the same type that is listening on the
	 * address we want to connect to
	 */
	for (i = 0; i < NR_FDS; i++) {

		if (uds_fd_table[minor].type == uds_fd_table[i].type &&
			uds_fd_table[i].listening &&
			uds_fd_table[i].addr.sun_family == AF_UNIX &&
			!strncmp(addr.sun_path, uds_fd_table[i].addr.sun_path,
			UNIX_PATH_MAX)) {

			if ((child = uds_fd_table[i].child) != -1) {

				/* the server is blocked on accept(2) --
				 * perform connection to the child
				 */

				rc = perform_connection(dev_m_in, dev_m_out,
					&addr, minor, child);

				if (rc == OK) {

					uds_fd_table[i].child = -1;

#if DEBUG == 1
		printf("(uds) [%d] {do_connect} revive %d\n", minor, child);
#endif

					/* wake the parent (server) */
					uds_fd_table[child].ready_to_revive =
						1;
					uds_unsuspend(dev_m_in->m_source,
						child);
				}

				return rc;

			} else {

#if DEBUG == 1
				printf("(uds) [%d] adding to %d's backlog\n",
								minor, i);
#endif

				/* tell the server were waiting to be served */

				/* look for a free slot in the backlog */
				rc = -1; /* to trap error */
				for (j = 0; j < uds_fd_table[i].backlog_size;
					j++) {

					if (uds_fd_table[i].backlog[j] == -1) {

						uds_fd_table[i].backlog[j] =
							minor;

						rc = 0;
						break;
					}
				}

				if (rc == -1) {

					/* backlog is full */
					break;
				}

				/* see if the server is blocked on select() */
				if (uds_fd_table[i].selecting == 1) {

					/* if the server wants to know
					 * about data ready to read and
					 * it doesn't know about it
					 * already, then let the server
					 * know we have data for it.
					 */
					if ((uds_fd_table[i].sel_ops_in &
						SEL_RD) &&
						!(uds_fd_table[i].sel_ops_out &
						SEL_RD)) {

						uds_fd_table[i].sel_ops_out |=
							SEL_RD;
						uds_fd_table[i].status_updated
							= 1;

						uds_unsuspend(
						dev_m_in->m_source, i);
					}
				}

				/* we found our server */
				uds_fd_table[minor].peer = i;

				/* set the address */
				memcpy(&(uds_fd_table[minor].addr), &addr,
					sizeof(struct sockaddr_un));

				break;
			}
		}
	}

	if (uds_fd_table[minor].peer == -1) {
		/* could not find another open socket listening on the
		 * specified address with room in the backlog
		 */
		return ECONNREFUSED;
	}

#if DEBUG == 1
	printf("(uds) [%d] {do_connect} suspend\n", minor);
#endif

	/* suspend until the server side completes the connection with accept()
	 */

	uds_fd_table[minor].suspended = UDS_SUSPENDED_CONNECT;

	return SUSPEND;
}
Ejemplo n.º 6
0
int do_accept(message *dev_m_in, message *dev_m_out)
{
	int minor;
	int minorparent; /* minor number of parent (server) */
	int minorpeer;
	int rc, i;
	struct sockaddr_un addr;

#if DEBUG == 1
	static int call_count = 0;
	printf("(uds) [%d] do_accept() call_count=%d\n",
					uds_minor(dev_m_in), ++call_count);
#endif

	/* Somewhat weird logic is used in this function, so here's an
	 * overview... The minor number is the server's client socket
	 * (the socket to be returned by accept()). The data waiting
	 * for us in the IO Grant is the address that the server is
	 * listening on. This function uses the address to find the
	 * server's descriptor. From there we can perform the
	 * connection or suspend and wait for a connect().
	 */

	minor = uds_minor(dev_m_in);

	if (uds_fd_table[minor].type != -1) {
		/* this IOCTL must be called on a 'fresh' socket */
		return EINVAL;
	}

	/* Get the server's address */
	rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT,
		(vir_bytes) 0, (vir_bytes) &addr, sizeof(struct sockaddr_un));

	if (rc != OK) {
		return EIO;
	}

	/* locate server socket */
	rc = -1; /* to trap error */

	for (i = 0; i < NR_FDS; i++) {

		if (uds_fd_table[i].addr.sun_family == AF_UNIX &&
				!strncmp(addr.sun_path,
				uds_fd_table[i].addr.sun_path,
				UNIX_PATH_MAX) &&
				uds_fd_table[i].listening == 1) {

			rc = 0;
			break;
		}
	}

	if (rc == -1) {
		/* there is no server listening on addr. Maybe someone
		 * screwed up the ioctl()?
		 */
		return EINVAL;
	}

	minorparent = i; /* parent */

	/* we are the parent's child */
	uds_fd_table[minorparent].child = minor;

	/* the peer has the same type as the parent. we need to be that
	 * type too.
	 */
	uds_fd_table[minor].type = uds_fd_table[minorparent].type;

	/* locate peer to accept in the parent's backlog */
	minorpeer = -1; /* to trap error */
	for (i = 0; i < uds_fd_table[minorparent].backlog_size; i++) {
		if (uds_fd_table[minorparent].backlog[i] != -1) {
			minorpeer = uds_fd_table[minorparent].backlog[i];
			uds_fd_table[minorparent].backlog[i] = -1;
			rc = 0;
			break;
		}
	}

	if (minorpeer == -1) {

#if DEBUG == 1
		printf("(uds) [%d] {do_accept} suspend\n", minor);
#endif

		/* there are no peers in the backlog, suspend and wait
		 * for some to show up
		 */
		uds_fd_table[minor].suspended = UDS_SUSPENDED_ACCEPT;

		return SUSPEND;
	}

#if DEBUG == 1
	printf("(uds) [%d] connecting to %d -- parent is %d\n", minor,
						minorpeer, minorparent);
#endif

	rc = perform_connection(dev_m_in, dev_m_out, &addr, minor, minorpeer);
	if (rc != OK) {
#if DEBUG == 1
		printf("(uds) [%d] {do_accept} connection not performed\n",
								minor);
#endif
		return rc;
	}

	uds_fd_table[minorparent].child = -1;

	/* if peer is blocked on connect() revive peer */
	if (uds_fd_table[minorpeer].suspended) {
#if DEBUG == 1
		printf("(uds) [%d] {do_accept} revive %d\n", minor,
								minorpeer);
#endif
		uds_fd_table[minorpeer].ready_to_revive = 1;
		uds_unsuspend(dev_m_in->m_source, minorpeer);
	}

	return OK;
}