示例#1
0
int main(int argc, char **argv)
{
	int c;
	int port = 0;
	int state = 0, sflag = 0;
	char mon_client[STR_SIZE], mflag = 0;
	char remote_addr_s[STR_SIZE], rflag = 0;
	char local_addr_s[STR_SIZE], lflag = 0;
	notify arg;
	CLIENT *clnt;
	struct netbuf *buf;
	char port_str[20];

	struct sockaddr_in local_addr;

	int fd;

	while ((c = getopt(argc, argv, "p:r:m:l:s:")) != EOF)
		switch (c) {
		case 'p':
			port = atoi(optarg);
			break;
		case 's':
			state = atoi(optarg);
			sflag = 1;
			break;
		case 'm':
			if (strlen(optarg) >= STR_SIZE) {
				fprintf(stderr, ERR_MSG1, "monitor host");
				exit(1);
			}
			strcpy(mon_client, optarg);
			mflag = 1;
			break;
		case 'r':
			if (strlen(optarg) >= STR_SIZE) {
				fprintf(stderr, ERR_MSG1, "remote address");
				exit(1);
			}
			strcpy(remote_addr_s, optarg);
			rflag = 1;
			break;
		case 'l':
			if (strlen(optarg) >= STR_SIZE) {
				fprintf(stderr, ERR_MSG1, "local address");
				exit(1);
			}
			strcpy(local_addr_s, optarg);
			lflag = 1;
			break;
		case '?':
		default:
			fprintf(stderr, USAGE, argv[0]);
			exit(1);
			break;
	}

	if ((sflag + lflag + mflag + rflag) != 4) {
		fprintf(stderr, USAGE, argv[0]);
		exit(1);
	}


	/* create a udp socket */
	fd = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_UDP);
	if (fd < 0) {
		fprintf(stderr, "socket call failed. errno=%d\n", errno);
		exit(1);
	}

	/* set up the sockaddr for local endpoint */
	memset(&local_addr, 0, sizeof(struct sockaddr_in));
	local_addr.sin_family = PF_INET;
	local_addr.sin_port = htons(port);
	local_addr.sin_addr.s_addr = inet_addr(local_addr_s);

	if (bind(fd, (struct sockaddr *)&local_addr,
			sizeof(struct sockaddr)) < 0) {
		fprintf(stderr, "bind call failed. errno=%d\n", errno);
		exit(1);
	}

	/* find the port for SM service of the remote server */
	buf = rpcb_find_mapped_addr(
				"udp",
				SM_PROG, SM_VERS,
				remote_addr_s);

	/* handle error here, for example,
	 * client side blocking rpc call
	 */
	if (buf == NULL) {
		close(fd);
		exit(1);
	}

	/* convert port to string format */
	sprintf(port_str, "%d",
		htons(((struct sockaddr_in *)
		buf->buf)->sin_port));

	clnt = clnt_dg_ncreate(fd, buf, SM_PROG,
			SM_VERS, 0, 0);

	arg.my_name = mon_client;
	arg.state = state;
	nsm_notify_1(&arg, clnt);

	/* free resources */
	gsh_free(buf->buf);
	gsh_free(buf);
	clnt_destroy(clnt);

	close(fd);

	return 0;
}
示例#2
0
/* Client routine  to send the asynchrnous response,
 * key is used to wait for a response
 */
int nlm_send_async(int proc, state_nlm_client_t *host, void *inarg, void *key)
{
	struct timeval tout = { 0, 10 };
	int retval, retry;
	struct timeval start, now;
	struct timespec timeout;

	for (retry = 1; retry <= MAX_ASYNC_RETRY; retry++) {
		if (host->slc_callback_clnt == NULL) {
			LogFullDebug(COMPONENT_NLM,
				     "gsh_clnt_create %s",
				     host->slc_nsm_client->ssc_nlm_caller_name);

			if (host->slc_client_type == XPRT_TCP) {
				int fd;
				struct sockaddr_in6 server_addr;
				struct netbuf *buf, local_buf;
				struct addrinfo *result;
				struct addrinfo hints;
				char port_str[20];

				fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
				if (fd < 0)
					return -1;

				memcpy(&server_addr,
				       &(host->slc_server_addr),
				       sizeof(struct sockaddr_in6));
				server_addr.sin6_port = 0;

				if (bind(fd,
					 (struct sockaddr *)&server_addr,
					  sizeof(server_addr)) == -1) {
					LogMajor(COMPONENT_NLM, "Cannot bind");
					close(fd);
					return -1;
				}

				buf = rpcb_find_mapped_addr(
				     (char *) xprt_type_to_str(
							host->slc_client_type),
				     NLMPROG, NLM4_VERS,
				     host->slc_nsm_client->ssc_nlm_caller_name);
				/* handle error here, for example,
				 * client side blocking rpc call
				 */
				if (buf == NULL) {
					LogMajor(COMPONENT_NLM,
						 "Cannot create NLM async %s connection to client %s",
						 xprt_type_to_str(
							host->slc_client_type),
						 host->slc_nsm_client->
						 ssc_nlm_caller_name);
					close(fd);
					return -1;
				}

				memset(&hints, 0, sizeof(struct addrinfo));
				hints.ai_family = AF_INET6;	/* only INET6 */
				hints.ai_socktype = SOCK_STREAM; /* TCP */
				hints.ai_protocol = 0;	/* Any protocol */
				hints.ai_canonname = NULL;
				hints.ai_addr = NULL;
				hints.ai_next = NULL;

				/* convert port to string format */
				sprintf(port_str, "%d",
					htons(((struct sockaddr_in *)
						buf->buf)->sin_port));

				/* buf with inet is only needed for the port */
				gsh_free(buf->buf);
				gsh_free(buf);

				/* get the IPv4 mapped IPv6 address */
				getaddrinfo(host->slc_nsm_client->
					    ssc_nlm_caller_name,
					    port_str,
					    &hints,
					    &result);

				/* setup the netbuf with in6 address */
				local_buf.buf = result->ai_addr;
				local_buf.len = local_buf.maxlen =
				    result->ai_addrlen;

				host->slc_callback_clnt =
				    clnt_vc_ncreate(fd, &local_buf, NLMPROG,
						    NLM4_VERS, 0, 0);
				freeaddrinfo(result);
			} else {

				host->slc_callback_clnt = gsh_clnt_create(
				    host->slc_nsm_client->ssc_nlm_caller_name,
				    NLMPROG,
				    NLM4_VERS,
				    (char *) xprt_type_to_str(
						host->slc_client_type));
			}

			if (host->slc_callback_clnt == NULL) {
				LogMajor(COMPONENT_NLM,
					 "Cannot create NLM async %s connection to client %s",
					 xprt_type_to_str(host->
							  slc_client_type),
					 host->slc_nsm_client->
					 ssc_nlm_caller_name);
				return -1;
			}

			/* split auth (for authnone, idempotent) */
			host->slc_callback_auth = authnone_create();
		}

		PTHREAD_MUTEX_lock(&nlm_async_resp_mutex);
		resp_key = key;
		PTHREAD_MUTEX_unlock(&nlm_async_resp_mutex);

		LogFullDebug(COMPONENT_NLM, "About to make clnt_call");

		retval = clnt_call(host->slc_callback_clnt,
				   host->slc_callback_auth,
				   proc,
				   nlm_reply_proc[proc],
				   inarg,
				   (xdrproc_t) xdr_void,
				   NULL,
				   tout);

		LogFullDebug(COMPONENT_NLM, "Done with clnt_call");

		if (retval == RPC_TIMEDOUT || retval == RPC_SUCCESS) {
			retval = RPC_SUCCESS;
			break;
		}

		LogCrit(COMPONENT_NLM,
			"NLM async Client procedure call %d failed with return code %d %s",
			proc, retval,
			clnt_sperror(host->slc_callback_clnt, ""));

		gsh_clnt_destroy(host->slc_callback_clnt);
		host->slc_callback_clnt = NULL;

		if (retry == MAX_ASYNC_RETRY) {
			LogMajor(COMPONENT_NLM,
				 "NLM async Client exceeded retry count %d",
				 MAX_ASYNC_RETRY);
			PTHREAD_MUTEX_lock(&nlm_async_resp_mutex);
			resp_key = NULL;
			PTHREAD_MUTEX_unlock(&nlm_async_resp_mutex);
			return retval;
		}
	}

	PTHREAD_MUTEX_lock(&nlm_async_resp_mutex);

	if (resp_key != NULL) {
		/* Wait for 5 seconds or a signal */
		gettimeofday(&start, NULL);
		gettimeofday(&now, NULL);
		timeout.tv_sec = 5 + start.tv_sec;
		timeout.tv_nsec = 0;

		LogFullDebug(COMPONENT_NLM,
			     "About to wait for signal for key %p", resp_key);

		while (resp_key != NULL && now.tv_sec < (start.tv_sec + 5)) {
			int rc;
			rc = pthread_cond_timedwait(&nlm_async_resp_cond,
						    &nlm_async_resp_mutex,
						    &timeout);
			LogFullDebug(COMPONENT_NLM,
				     "pthread_cond_timedwait returned %d",
				     rc);
			gettimeofday(&now, NULL);
		}
		LogFullDebug(COMPONENT_NLM, "Done waiting");
	}

	PTHREAD_MUTEX_unlock(&nlm_async_resp_mutex);

	return retval;
}