161 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef __NET_SERVER_SOCKET_H__
 | |
| #define __NET_SERVER_SOCKET_H__
 | |
| 
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #include <minix/ipc.h>
 | |
| #include <minix/endpoint.h>
 | |
| #include <minix/chardriver.h>
 | |
| 
 | |
| /*
 | |
|  * User can set this variable to make the debugging output differ between
 | |
|  * various users, e.g. "TCP" or "UDP"
 | |
|  */
 | |
| extern char * netsock_user_name;
 | |
| 
 | |
| #define SOCK_TYPE_IP	0
 | |
| #define SOCK_TYPE_TCP	1
 | |
| #define SOCK_TYPE_UDP	2
 | |
| #define SOCK_TYPES	3
 | |
| 
 | |
| struct socket;
 | |
| struct sock_req;
 | |
| 
 | |
| typedef int (* sock_op_opcl_t)(struct socket *);
 | |
| typedef int (* sock_op_io_t)(struct socket *, struct sock_req *, int blk);
 | |
| typedef int (* sock_op_select_t)(struct socket *, unsigned int);
 | |
| typedef int (* sock_op_select_reply_t)(struct socket *);
 | |
| 
 | |
| struct sock_ops {
 | |
| 	sock_op_opcl_t		open;
 | |
| 	sock_op_opcl_t		close;
 | |
| 	sock_op_io_t		read;
 | |
| 	sock_op_io_t		write;
 | |
| 	sock_op_io_t		ioctl;
 | |
| 	sock_op_select_t	select;
 | |
| 	sock_op_select_reply_t	select_reply;
 | |
| };
 | |
| 
 | |
| struct recv_q {
 | |
| 	struct recv_q *	next;
 | |
| 	void *		data;
 | |
| };
 | |
| 
 | |
| #define SOCK_FLG_OP_PENDING	0x1
 | |
| #define SOCK_FLG_OP_IOCTL	0x10
 | |
| #define SOCK_FLG_OP_LISTENING	0x100	/* tcp socket is in a listening mode */
 | |
| #define	SOCK_FLG_OP_CONNECTING	0x200	/* set when waiting for a connect */
 | |
| #define SOCK_FLG_OP_READING	0x400	/* reading operation in progress */
 | |
| #define SOCK_FLG_OP_WRITING	0x800	/* writing operation in progress */
 | |
| #define SOCK_FLG_CLOSED		0x1000	/* tcp socket has been closed do not
 | |
| 					   expect any more data */
 | |
| /* select() flags - they say what action do we monitor */
 | |
| #define SOCK_FLG_SEL_WRITE	0x100000
 | |
| #define SOCK_FLG_SEL_READ	0x200000
 | |
| #define SOCK_FLG_SEL_ERROR	0x400000
 | |
| 
 | |
| #define sock_select_set(sock)	((sock)->flags & (SOCK_FLG_SEL_WRITE |	\
 | |
| 				SOCK_FLG_SEL_READ | SOCK_FLG_SEL_ERROR))
 | |
| #define sock_select_read_set(sock)	((sock)->flags & SOCK_FLG_SEL_READ)
 | |
| #define sock_select_write_set(sock)	((sock)->flags & SOCK_FLG_SEL_WRITE)
 | |
| #define sock_select_rw_set(sock)	((sock)->flags & (SOCK_FLG_SEL_READ | \
 | |
| 							SOCK_FLG_SEL_WRITE))
 | |
| #define sock_select_error_set(sock)	((sock)->flags & SOCK_FLG_SEL_ERROR)
 | |
| #define sock_clear_select(sock)	do {					\
 | |
| 	(sock)->flags &= ~(SOCK_FLG_SEL_READ | SOCK_FLG_SEL_WRITE |	\
 | |
| 						SOCK_FLG_SEL_ERROR);	\
 | |
| } while (0)
 | |
| 
 | |
| struct sock_req {
 | |
| 	enum {
 | |
| 		SOCK_REQ_READ,
 | |
| 		SOCK_REQ_WRITE,
 | |
| 		SOCK_REQ_IOCTL
 | |
| 	}			type;
 | |
| 	devminor_t		minor;
 | |
| 	endpoint_t		endpt;
 | |
| 	cp_grant_id_t		grant;
 | |
| 	union {
 | |
| 		size_t		size;	/* for SOCK_REQ_READ, SOCK_REQ_WRITE */
 | |
| 		unsigned long	req;	/* for SOCK_REQ_IOCTL */
 | |
| 	};
 | |
| 	int			flags;
 | |
| 	cdev_id_t		id;
 | |
| };
 | |
| 
 | |
| struct socket {
 | |
| 	int			type;
 | |
| 	u32_t			flags;
 | |
| 	unsigned long		usr_flags;
 | |
| 	void *			pcb;
 | |
| 	struct sock_ops *	ops;
 | |
| 	void *			buf;
 | |
| 	size_t			buf_size;
 | |
| 	struct sock_req		req;
 | |
| 	void *			shm;
 | |
| 	size_t			shm_size;
 | |
| 	endpoint_t		select_ep;
 | |
| 	struct recv_q *		recv_head;
 | |
| 	struct recv_q *		recv_tail;
 | |
| 	unsigned		recv_data_size; /* sum of data enqueued */
 | |
| 	void *			data;
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Each component needs to provide a method how to initially open a socket.
 | |
|  * The rest is handled byt the socket library.
 | |
|  */
 | |
| int socket_open(devminor_t minor);
 | |
| 
 | |
| #define get_sock_num(x) ((long int) ((x) - socket))
 | |
| #define is_valid_sock_num(x) (x < MAX_SOCKETS)
 | |
| #define get_sock(x) &socket[x]
 | |
| 
 | |
| #define MAX_SOCKETS 255 /* FIXME as log as the sockets are identified by the
 | |
| 			   minor device number 255 is ok */
 | |
| #define MAX_DEVS 5
 | |
| #define RESERVED (SOCK_TYPES + MAX_DEVS) /* rounded to 8 */
 | |
| 
 | |
| extern struct socket socket[MAX_SOCKETS];
 | |
| 
 | |
| void socket_request(message * m, int ipc_status);
 | |
| void mq_process(void);
 | |
| 
 | |
| struct socket * get_unused_sock(void);
 | |
| struct socket * get_nic_sock(unsigned dev);
 | |
| 
 | |
| void send_req_reply(struct sock_req * req, int status);
 | |
| 
 | |
| typedef void (* recv_data_free_fn)(void *);
 | |
| 
 | |
| int sock_enqueue_data(struct socket * sock, void * data, unsigned size);
 | |
| void * sock_dequeue_data(struct socket * sock);
 | |
| void sock_dequeue_data_all(struct socket * sock,
 | |
| 				recv_data_free_fn data_free);
 | |
| 
 | |
| void sock_select_notify(struct socket * sock);
 | |
| 
 | |
| static inline void * debug_malloc(size_t s)
 | |
| {
 | |
| 	void * ret;
 | |
| 
 | |
| 	ret = malloc(s);
 | |
| 	// printf("allocated %p size %d\n", ret, s);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| #define debug_free(x) do {							\
 | |
| 	if (0)									\
 | |
| 		printf("free called from %s:%d %s freeing %p\n", __FILE__,	\
 | |
| 						__LINE__, __func__, (x));	\
 | |
| 	free(x);								\
 | |
| } while(0)
 | |
| 
 | |
| int generic_op_select(struct socket * sock, unsigned int sel);
 | |
| int generic_op_select_reply(struct socket * sock);
 | |
| 
 | |
| /* a function thr user has to provide to reply to the posix server */
 | |
| void posix_reply(endpoint_t ep, message * m);
 | |
| 
 | |
| #endif /* __NET_SERVER_SOCKET_H__ */
 | 
