Пример #1
0
static void
ndma_proxy_session (struct ndm_session *sess, int proxy_port)
{
	int			conn_sock, len, rc;
	struct sockaddr		sa;
	int			proxy_sock;
	int			fd;

	sess->proxy_starting = TRUE;
	sess->proxy_connections = 0;

	proxy_sock = socket (AF_INET, SOCK_STREAM, 0);
	if (proxy_sock < 0) {
		fprintf(stdout, "opening socket: %s\n", strerror(errno));
		exit(1);
	}

	ndmalogf (sess, 0, 2, "set sess->protocol_listen");

	ndmos_condition_listen_socket (sess, proxy_sock);

	NDMOS_MACRO_SET_SOCKADDR(&sa, 0, proxy_port);

	if (bind (proxy_sock, &sa, sizeof sa) < 0) {
		int err = errno;
		ndmalogf (sess, 0, 2, "Can't bind the socket(%d): %s\n", proxy_port, strerror(err));
		if (err == EADDRINUSE) {
		    fprintf(stdout, "INUSE\n");
		    fflush(stdout);
		    exit(0);
		} else {
		    fprintf(stdout, "while binding tcp port %d: %s\n", proxy_port, strerror(err));
		    fflush(stdout);
		    exit(1);
		}
	}

	if (listen (proxy_sock, 5) < 0) {
		fprintf(stdout, "listening on socket: %s\n", strerror(errno));
		exit(1);
	}

	/* set up to listen on this new socket */
	ndmchan_initialize(&sess->listen_chan, "proxy-listen");
	ndmchan_start_listen(&sess->listen_chan, proxy_sock);

	/* tell our invoker that we are OK */
	if (full_write(1, "OK\n", 3) != 3) {
		fprintf(stderr, "ndmp-proxy writing to stdout: %s\n", strerror(errno));
		exit(1);
	}

	/* send an EOF on stdout */
	close(1);

	/* open /dev/null on fds 0 and 1 */
	fd = open("/dev/null", O_RDONLY);
	if (fd < 0) {
	    fprintf(stderr, "cannot open /dev/null\n");
	    /* ignore the error */
	} else if (fd != 1) {
	    dup2(fd, 1);
	    close(fd);
	}

	fd = open("/dev/null", O_WRONLY);
	if (fd < 0) {
	    fprintf(stderr, "cannot open /dev/null\n");
	    /* ignore the error */
	} else if (fd != 0) {
	    dup2(fd, 0);
	    close(fd);
	}
}
Пример #2
0
int
ndmis_tcp_listen (struct ndm_session *sess, struct ndmp9_addr *listen_addr)
{
	struct ndm_image_stream *is = &sess->plumb.image_stream;
	ndmp9_tcp_addr *	tcp_addr = &listen_addr->ndmp9_addr_u.tcp_addr;
	struct ndmconn *	conn;
	struct sockaddr		c_sa;
	struct sockaddr		l_sa;
	struct sockaddr_in *	sin;
	socklen_t		len;
	int			listen_sock = -1;
	char *			what = "???";

	/*
	 * Get the IP address thru which the CONTROL agent connected
	 * to this session. The CONTROL agent may influence the
	 * network used for the image-stream on multi-homed hosts
	 * simply by connecting to the prefered IP address.
	 */
	what = "determine-conn";
	conn = sess->plumb.control;
	if (!conn || conn->conn_type != NDMCONN_TYPE_REMOTE) {
		/*
		 * If CONTROL is resident, try the other
		 * control connections in hopes of finding
		 * a clue about what IP address to offer.
		 */
		conn = sess->plumb.data;
		if (!conn || conn->conn_type != NDMCONN_TYPE_REMOTE) {
			conn = sess->plumb.tape;
			if (!conn || conn->conn_type != NDMCONN_TYPE_REMOTE) {
				conn = 0;
			}
		}
	}

	if (conn) {
		/*
		 * We found a connection to use for determining
		 * what IP address to offer.
		 */
		what = "getsockname-ctrl";
		len = sizeof c_sa;
		if (getsockname (ndmconn_fileno(conn), &c_sa, &len) < 0) {
			/* we'll try the fallback rules */
			conn = 0;
		}
	}

	if (!conn) {
		/*
		 * For whatever reason, we can't determine a good
		 * IP address from the connections. Try the boring
		 * fallback rules.
		 */
		ndmos_sync_config_info (sess);

		sin = (struct sockaddr_in *) &c_sa;

		what = "ndmhost_lookup";
		if (ndmhost_lookup (sess->config_info.hostname, sin) != 0)
			goto fail;
	}

	/* c_sa is a sockaddr_in for the IP address to use */

	what = "socket";
	listen_sock = socket (AF_INET, SOCK_STREAM, 0);
	if (listen_sock < 0) goto fail;

	/* could bind() to more restrictive addr based on c_sa */
	NDMOS_MACRO_SET_SOCKADDR(&l_sa, 0, 0);
	what = "bind";
	if (bind (listen_sock, &l_sa, sizeof l_sa) < 0) goto fail;

	what = "listen";
	if (listen (listen_sock, 1) < 0) goto fail;

	ndmos_condition_listen_socket (sess, listen_sock);

	/* Get the port */
	what = "getsockname-listen";
	len = sizeof l_sa;
	if (getsockname (listen_sock, &l_sa, &len) < 0) goto fail;

	/*
	 * Fill in the return address
	 */

	listen_addr->addr_type = NDMP9_ADDR_TCP;
	tcp_addr = &listen_addr->ndmp9_addr_u.tcp_addr;

	/* IP addr from CONTROL connection, or where ever c_sa came from */
	sin = (struct sockaddr_in *) &c_sa;
	tcp_addr->ip_addr = ntohl (sin->sin_addr.s_addr);

	/* port from the bind() and getsockname() above */
	sin = (struct sockaddr_in *) &l_sa;
	tcp_addr->port = ntohs (sin->sin_port);

	/*
	 * Start the listen channel
	 */

	ndmchan_start_listen (&is->remote.listen_chan, listen_sock);

	is->remote.connect_status = NDMIS_CONN_LISTEN;
	is->remote.listen_addr = *listen_addr;

	return 0;

  fail:
	ndmalogf (sess, 0, 2, "ndmis_tcp_listen(): %s failed", what);
	if (listen_sock >= 0) close (listen_sock);

	return -1;
}