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

📄 sock.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
						if (result < 8 + 8) {							result = -EIO;						} else {							unsigned int hdrl;														result -= 8;							hdrl = sock->sk->sk_family == AF_INET ? 8 : 6;							if (sign_verify_reply(server, server->rxbuf + hdrl, result - hdrl, cpu_to_le32(result), server->rxbuf + result)) {								printk(KERN_INFO "ncpfs: Signature violation\n");								result = -EIO;							}						}					}#endif					del_timer(&server->timeout_tm);				     	server->rcv.creq = NULL;					ncp_finish_request(server, req, result);					__ncp_next_request(server);					mutex_unlock(&server->rcv.creq_mutex);					continue;				}			}			mutex_unlock(&server->rcv.creq_mutex);		}drop:;				_recv(sock, &reply, sizeof(reply), MSG_DONTWAIT);	}}static void __ncpdgram_timeout_proc(struct ncp_server *server){	/* If timer is pending, we are processing another request... */	if (!timer_pending(&server->timeout_tm)) {		struct ncp_request_reply* req;				req = server->rcv.creq;		if (req) {			int timeout;						if (server->m.flags & NCP_MOUNT_SOFT) {				if (server->timeout_retries-- == 0) {					__ncp_abort_request(server, req, -ETIMEDOUT);					return;				}			}			/* Ignore errors */			ncpdgram_send(server->ncp_sock, req);			timeout = server->timeout_last << 1;			if (timeout > NCP_MAX_RPC_TIMEOUT) {				timeout = NCP_MAX_RPC_TIMEOUT;			}			server->timeout_last = timeout;			mod_timer(&server->timeout_tm, jiffies + timeout);		}	}}void ncpdgram_timeout_proc(struct work_struct *work){	struct ncp_server *server =		container_of(work, struct ncp_server, timeout_tq);	mutex_lock(&server->rcv.creq_mutex);	__ncpdgram_timeout_proc(server);	mutex_unlock(&server->rcv.creq_mutex);}static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len){	int result;		if (buffer) {		result = _recv(server->ncp_sock, buffer, len, MSG_DONTWAIT);	} else {		static unsigned char dummy[1024];					if (len > sizeof(dummy)) {			len = sizeof(dummy);		}		result = _recv(server->ncp_sock, dummy, len, MSG_DONTWAIT);	}	if (result < 0) {		return result;	}	if (result > len) {		printk(KERN_ERR "ncpfs: tcp: bug in recvmsg (%u > %Zu)\n", result, len);		return -EIO;				}	return result;}	static int __ncptcp_rcv_proc(struct ncp_server *server){	/* We have to check the result, so store the complete header */	while (1) {		int result;		struct ncp_request_reply *req;		int datalen;		int type;		while (server->rcv.len) {			result = do_tcp_rcv(server, server->rcv.ptr, server->rcv.len);			if (result == -EAGAIN) {				return 0;			}			if (result <= 0) {				req = server->rcv.creq;				if (req) {					__ncp_abort_request(server, req, -EIO);				} else {					__ncptcp_abort(server);				}				if (result < 0) {					printk(KERN_ERR "ncpfs: tcp: error in recvmsg: %d\n", result);				} else {					DPRINTK(KERN_ERR "ncpfs: tcp: EOF\n");				}				return -EIO;			}			if (server->rcv.ptr) {				server->rcv.ptr += result;			}			server->rcv.len -= result;		}		switch (server->rcv.state) {			case 0:				if (server->rcv.buf.magic != htonl(NCP_TCP_RCVD_MAGIC)) {					printk(KERN_ERR "ncpfs: tcp: Unexpected reply type %08X\n", ntohl(server->rcv.buf.magic));					__ncptcp_abort(server);					return -EIO;				}				datalen = ntohl(server->rcv.buf.len) & 0x0FFFFFFF;				if (datalen < 10) {					printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d\n", datalen);					__ncptcp_abort(server);					return -EIO;				}#ifdef CONFIG_NCPFS_PACKET_SIGNING								if (server->sign_active) {					if (datalen < 18) {						printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d\n", datalen);						__ncptcp_abort(server);						return -EIO;					}					server->rcv.buf.len = datalen - 8;					server->rcv.ptr = (unsigned char*)&server->rcv.buf.p1;					server->rcv.len = 8;					server->rcv.state = 4;					break;				}#endif								type = ntohs(server->rcv.buf.type);#ifdef CONFIG_NCPFS_PACKET_SIGNING				cont:;				#endif				if (type != NCP_REPLY) {					if (datalen - 8 <= sizeof(server->unexpected_packet.data)) {						*(__u16*)(server->unexpected_packet.data) = htons(type);						server->unexpected_packet.len = datalen - 8;						server->rcv.state = 5;						server->rcv.ptr = server->unexpected_packet.data + 2;						server->rcv.len = datalen - 10;						break;					}										DPRINTK("ncpfs: tcp: Unexpected NCP type %02X\n", type);skipdata2:;					server->rcv.state = 2;skipdata:;					server->rcv.ptr = NULL;					server->rcv.len = datalen - 10;					break;				}				req = server->rcv.creq;				if (!req) {					DPRINTK(KERN_ERR "ncpfs: Reply without appropriate request\n");					goto skipdata2;				}				if (datalen > req->datalen + 8) {					printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d (expected at most %Zd)\n", datalen, req->datalen + 8);					server->rcv.state = 3;					goto skipdata;				}				req->datalen = datalen - 8;				((struct ncp_reply_header*)server->rxbuf)->type = NCP_REPLY;				server->rcv.ptr = server->rxbuf + 2;				server->rcv.len = datalen - 10;				server->rcv.state = 1;				break;#ifdef CONFIG_NCPFS_PACKET_SIGNING							case 4:				datalen = server->rcv.buf.len;				type = ntohs(server->rcv.buf.type2);				goto cont;#endif			case 1:				req = server->rcv.creq;				if (req->tx_type != NCP_ALLOC_SLOT_REQUEST) {					if (((struct ncp_reply_header*)server->rxbuf)->sequence != server->sequence) {						printk(KERN_ERR "ncpfs: tcp: Bad sequence number\n");						__ncp_abort_request(server, req, -EIO);						return -EIO;					}					if ((((struct ncp_reply_header*)server->rxbuf)->conn_low | (((struct ncp_reply_header*)server->rxbuf)->conn_high << 8)) != server->connection) {						printk(KERN_ERR "ncpfs: tcp: Connection number mismatch\n");						__ncp_abort_request(server, req, -EIO);						return -EIO;					}				}#ifdef CONFIG_NCPFS_PACKET_SIGNING								if (server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) {					if (sign_verify_reply(server, server->rxbuf + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) {						printk(KERN_ERR "ncpfs: tcp: Signature violation\n");						__ncp_abort_request(server, req, -EIO);						return -EIO;					}				}#endif								ncp_finish_request(server, req, req->datalen);			nextreq:;				__ncp_next_request(server);			case 2:			next:;				server->rcv.ptr = (unsigned char*)&server->rcv.buf;				server->rcv.len = 10;				server->rcv.state = 0;				break;			case 3:				ncp_finish_request(server, server->rcv.creq, -EIO);				goto nextreq;			case 5:				info_server(server, 0, server->unexpected_packet.data, server->unexpected_packet.len);				goto next;		}	}}void ncp_tcp_rcv_proc(struct work_struct *work){	struct ncp_server *server =		container_of(work, struct ncp_server, rcv.tq);	mutex_lock(&server->rcv.creq_mutex);	__ncptcp_rcv_proc(server);	mutex_unlock(&server->rcv.creq_mutex);}void ncp_tcp_tx_proc(struct work_struct *work){	struct ncp_server *server =		container_of(work, struct ncp_server, tx.tq);		mutex_lock(&server->rcv.creq_mutex);	__ncptcp_try_send(server);	mutex_unlock(&server->rcv.creq_mutex);}static int do_ncp_rpc_call(struct ncp_server *server, int size,		unsigned char* reply_buf, int max_reply_size){	int result;	struct ncp_request_reply *req;	req = ncp_alloc_req();	if (!req)		return -ENOMEM;	req->reply_buf = reply_buf;	req->datalen = max_reply_size;	req->tx_iov[1].iov_base = server->packet;	req->tx_iov[1].iov_len = size;	req->tx_iovlen = 1;	req->tx_totallen = size;	req->tx_type = *(u_int16_t*)server->packet;	result = ncp_add_request(server, req);	if (result < 0)		goto out;	if (wait_event_interruptible(req->wq, req->status == RQ_DONE)) {		ncp_abort_request(server, req, -EINTR);		result = -EINTR;		goto out;	}	result = req->result;out:	ncp_req_put(req);	return result;}/* * We need the server to be locked here, so check! */static int ncp_do_request(struct ncp_server *server, int size,		void* reply, int max_reply_size){	int result;	if (server->lock == 0) {		printk(KERN_ERR "ncpfs: Server not locked!\n");		return -EIO;	}	if (!ncp_conn_valid(server)) {		printk(KERN_ERR "ncpfs: Connection invalid!\n");		return -EIO;	}	{		sigset_t old_set;		unsigned long mask, flags;		spin_lock_irqsave(&current->sighand->siglock, flags);		old_set = current->blocked;		if (current->flags & PF_EXITING)			mask = 0;		else			mask = sigmask(SIGKILL);		if (server->m.flags & NCP_MOUNT_INTR) {			/* FIXME: This doesn't seem right at all.  So, like,			   we can't handle SIGINT and get whatever to stop?			   What if we've blocked it ourselves?  What about			   alarms?  Why, in fact, are we mucking with the			   sigmask at all? -- r~ */			if (current->sighand->action[SIGINT - 1].sa.sa_handler == SIG_DFL)				mask |= sigmask(SIGINT);			if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL)				mask |= sigmask(SIGQUIT);		}		siginitsetinv(&current->blocked, mask);		recalc_sigpending();		spin_unlock_irqrestore(&current->sighand->siglock, flags);				result = do_ncp_rpc_call(server, size, reply, max_reply_size);		spin_lock_irqsave(&current->sighand->siglock, flags);		current->blocked = old_set;		recalc_sigpending();		spin_unlock_irqrestore(&current->sighand->siglock, flags);	}	DDPRINTK("do_ncp_rpc_call returned %d\n", result);	return result;}/* ncp_do_request assures that at least a complete reply header is * received. It assumes that server->current_size contains the ncp * request size */int ncp_request2(struct ncp_server *server, int function, 		void* rpl, int size){	struct ncp_request_header *h;	struct ncp_reply_header* reply = rpl;	int result;	h = (struct ncp_request_header *) (server->packet);	if (server->has_subfunction != 0) {		*(__u16 *) & (h->data[0]) = htons(server->current_size - sizeof(*h) - 2);	}	h->type = NCP_REQUEST;	/*	 * The server shouldn't know or care what task is making a	 * request, so we always use the same task number.	 */	h->task = 2; /* (current->pid) & 0xff; */	h->function = function;	result = ncp_do_request(server, server->current_size, reply, size);	if (result < 0) {		DPRINTK("ncp_request_error: %d\n", result);		goto out;	}	server->completion = reply->completion_code;	server->conn_status = reply->connection_state;	server->reply_size = result;	server->ncp_reply_size = result - sizeof(struct ncp_reply_header);	result = reply->completion_code;	if (result != 0)		PPRINTK("ncp_request: completion code=%x\n", result);out:	return result;}int ncp_connect(struct ncp_server *server){	struct ncp_request_header *h;	int result;	server->connection = 0xFFFF;	server->sequence = 255;	h = (struct ncp_request_header *) (server->packet);	h->type = NCP_ALLOC_SLOT_REQUEST;	h->task		= 2; /* see above */	h->function	= 0;	result = ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);	if (result < 0)		goto out;	server->connection = h->conn_low + (h->conn_high * 256);	result = 0;out:	return result;}int ncp_disconnect(struct ncp_server *server){	struct ncp_request_header *h;	h = (struct ncp_request_header *) (server->packet);	h->type = NCP_DEALLOC_SLOT_REQUEST;	h->task		= 2; /* see above */	h->function	= 0;	return ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);}void ncp_lock_server(struct ncp_server *server){	mutex_lock(&server->mutex);	if (server->lock)		printk(KERN_WARNING "ncp_lock_server: was locked!\n");	server->lock = 1;}void ncp_unlock_server(struct ncp_server *server){	if (!server->lock) {		printk(KERN_WARNING "ncp_unlock_server: was not locked!\n");		return;	}	server->lock = 0;	mutex_unlock(&server->mutex);}

⌨️ 快捷键说明

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