⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpc.c

📁 newos is new operation system
💻 C
字号:
/*** Copyright 2002, Travis Geiselbrecht. All rights reserved.** Distributed under the terms of the NewOS License.*/#include <kernel/kernel.h>#include <kernel/lock.h>#include <kernel/net/socket.h>#include <kernel/net/misc.h>#include <string.h>#include <stdlib.h>#include "rpc.h"int rpc_init_state(rpc_state *state){	memset(state, sizeof(rpc_state), 0);	// create a lock	mutex_init(&state->lock, "rpc_state");	state->socket = -1;	state->auth_cookie = rand();	return 0;}int rpc_destroy_state(rpc_state *state){	socket_close(state->socket);	mutex_destroy(&state->lock);	return 0;}int rpc_set_port(rpc_state *state, int port){	mutex_lock(&state->lock);	state->server_addr.port = port;	mutex_unlock(&state->lock);}int rpc_open_socket(rpc_state *state, netaddr *server_addr){	sockaddr saddr;	mutex_lock(&state->lock);	// XXX make better	saddr.port = 784;	saddr.addr.len = 4;	saddr.addr.type = ADDR_TYPE_IP;	memset(&saddr.addr.addr[0], 0, 4);	state->socket = socket_create(SOCK_PROTO_UDP, 0);	if(state->socket < 0) {		mutex_unlock(&state->lock);		return state->socket;	}	socket_bind(state->socket, &saddr);	state->server_addr.port = RPC_PORT;	memcpy(&state->server_addr.addr, server_addr, sizeof(netaddr));	mutex_unlock(&state->lock);	return NO_ERROR;}int rpc_call(rpc_state *state, unsigned int prog, unsigned int vers, unsigned int proc,	const void *out_data, int out_data_len, void *in_data, int in_data_len){	struct msg_header *header;	struct call_body *body;	struct auth *auth;	unsigned int xid;	int len;	int pos;	int err = 0;	sockaddr fromaddr;	mutex_lock(&state->lock);	// build the header	header = (struct msg_header *)&state->buf[0];	xid = rand();	header->xid = htonl(xid);	header->msg_type = htonl(RPC_CALL);	// this is a call	body = (struct call_body *)&state->buf[8];	body->rpcvers = htonl(RPC_VERS);	body->prog = htonl(prog);	body->vers = htonl(vers);	body->proc = htonl(proc);	len = 24;	// cred auth	auth = (struct auth *)&state->buf[len];	{		/* XXX do unix auth for now, make this smarter */		/* unix auth structure (from rfc 1057)		**	struct auth_unix {		**		unsigned int stamp;		**		string machinename<255>;		**		unsigned int uid;		**		unsigned int gid;		**		unsigned int gids<16>;		**	};		*/		int i = 0;		auth->auth_flavor = htonl(RPC_AUTH_UNIX);		auth->auth_len = -1; // fill this in later		// unsigned int stamp;		auth->data[i++] = state->auth_cookie;		// string machinename<255>;		auth->data[i++] = htonl(sizeof("newos")); // len		memcpy(&auth->data[i], "newos", sizeof("newos"));		i += ROUNDUP(sizeof("newos"), sizeof(unsigned int)) / sizeof(unsigned int);		// unsigned int uid;		auth->data[i++] = htonl(0);		// unsigned int gid;		auth->data[i++] = htonl(0);		// unsigned int gids<16>;		auth->data[i++] = htonl(0); // len		auth->auth_len = htonl(i * 4);		len += i * 4 + 8;	}	// verf auth	auth = (struct auth *)&state->buf[len];	auth[0].auth_flavor = htonl(RPC_AUTH_NULL);	auth[0].auth_len = 0;	len += 8;	// copy the passed in data to the buffer	if(out_data_len > 0) {		memcpy(&state->buf[len], out_data, out_data_len);		len += out_data_len;	}	// send the message	socket_sendto(state->socket, state->buf, len, &state->server_addr);	// wait for response	len = socket_recvfrom_etc(state->socket, state->buf, sizeof(state->buf), &fromaddr, SOCK_FLAG_TIMEOUT, 5000000);	if(len < 0) {		err = len;		dprintf("rpc_call: returned err %d from recv call\n", err);		goto err;	}//	dprintf("received response of len %d\n", len);	pos = 0;	// see if it's a response to this call	header = (struct msg_header *)&state->buf[pos];	if(ntohl(header->xid) != xid) {		dprintf("rpc_call: received response from different call (xid 0x%x)\n", ntohl(header->xid));		err = ERR_GENERAL;		goto err;	}//	dprintf("rpc_call: received message:\n");//	dprintf("\txid: 0x%x\n", ntohl(header->xid));	if(ntohl(header->msg_type) != RPC_REPLY) {		dprintf("rpc_call: did not receive reply\n");		err = ERR_GENERAL;		goto err;	}//	dprintf("\ttype: REPLY\n");	pos += 8;	switch(htonl(*(rpc_reply_stat *)&state->buf[pos])) {		case RPC_MSG_ACCEPTED://			dprintf("\treply stat: ACCEPTED\n");			pos += 4;			auth = (struct auth *)&state->buf[pos];//			dprintf("\tverf auth: flavor %d, len %d\n", ntohl(auth->auth_flavor), ntohl(auth->auth_len));			pos += 8 + ntohl(auth->auth_len);			if(htonl(*(rpc_accept_stat *)&state->buf[pos]) == RPC_SUCCESS) {//				dprintf("\taccept stat: SUCCESS\n");				pos += 4;				// good call, copy the remainder of the data to the out buffer				memcpy(in_data, &state->buf[pos], len - pos);				err = len - pos;			} else {//				dprintf("\taccept stat: %d\n", htonl(*(rpc_accept_stat *)&state->buf[pos]));				err = ERR_GENERAL;			}			break;		case RPC_MSG_DENIED://			dprintf("\treply stat: DENIED\n");			err = ERR_GENERAL;			break;	}err:	mutex_unlock(&state->lock);	return err;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -