1 | // Copyright (c) Athena Dev Teams - Licensed under GNU GPL |
---|
2 | // For more information, see LICENCE in the main folder |
---|
3 | |
---|
4 | #ifndef _SOCKET_H_ |
---|
5 | #define _SOCKET_H_ |
---|
6 | |
---|
7 | #ifndef _CBASETYPES_H_ |
---|
8 | #include "../common/cbasetypes.h" |
---|
9 | #endif |
---|
10 | |
---|
11 | #ifdef WIN32 |
---|
12 | #include <winsock2.h> |
---|
13 | typedef long in_addr_t; |
---|
14 | #else |
---|
15 | #include <sys/types.h> |
---|
16 | #include <sys/socket.h> |
---|
17 | #include <netinet/in.h> |
---|
18 | #endif |
---|
19 | |
---|
20 | #include <time.h> |
---|
21 | |
---|
22 | |
---|
23 | // socket I/O macros |
---|
24 | #define RFIFOHEAD(fd) |
---|
25 | #define WFIFOHEAD(fd, size) do{ if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) realloc_writefifo(fd, size); }while(0) |
---|
26 | #define RFIFOP(fd,pos) (session[fd]->rdata + session[fd]->rdata_pos + (pos)) |
---|
27 | #define WFIFOP(fd,pos) (session[fd]->wdata + session[fd]->wdata_size + (pos)) |
---|
28 | |
---|
29 | #define RFIFOB(fd,pos) (*(uint8*)RFIFOP(fd,pos)) |
---|
30 | #define WFIFOB(fd,pos) (*(uint8*)WFIFOP(fd,pos)) |
---|
31 | #define RFIFOW(fd,pos) (*(uint16*)RFIFOP(fd,pos)) |
---|
32 | #define WFIFOW(fd,pos) (*(uint16*)WFIFOP(fd,pos)) |
---|
33 | #define RFIFOL(fd,pos) (*(uint32*)RFIFOP(fd,pos)) |
---|
34 | #define WFIFOL(fd,pos) (*(uint32*)WFIFOP(fd,pos)) |
---|
35 | #define RFIFOSPACE(fd) (session[fd]->max_rdata - session[fd]->rdata_size) |
---|
36 | #define WFIFOSPACE(fd) (session[fd]->max_wdata - session[fd]->wdata_size) |
---|
37 | |
---|
38 | #define RFIFOREST(fd) (session[fd]->flag.eof ? 0 : session[fd]->rdata_size - session[fd]->rdata_pos) |
---|
39 | #define RFIFOFLUSH(fd) \ |
---|
40 | do { \ |
---|
41 | if(session[fd]->rdata_size == session[fd]->rdata_pos){ \ |
---|
42 | session[fd]->rdata_size = session[fd]->rdata_pos = 0; \ |
---|
43 | } else { \ |
---|
44 | session[fd]->rdata_size -= session[fd]->rdata_pos; \ |
---|
45 | memmove(session[fd]->rdata, session[fd]->rdata+session[fd]->rdata_pos, session[fd]->rdata_size); \ |
---|
46 | session[fd]->rdata_pos = 0; \ |
---|
47 | } \ |
---|
48 | } while(0) |
---|
49 | |
---|
50 | // buffer I/O macros |
---|
51 | #define RBUFP(p,pos) (((uint8*)(p)) + (pos)) |
---|
52 | #define RBUFB(p,pos) (*(uint8*)RBUFP((p),(pos))) |
---|
53 | #define RBUFW(p,pos) (*(uint16*)RBUFP((p),(pos))) |
---|
54 | #define RBUFL(p,pos) (*(uint32*)RBUFP((p),(pos))) |
---|
55 | |
---|
56 | #define WBUFP(p,pos) (((uint8*)(p)) + (pos)) |
---|
57 | #define WBUFB(p,pos) (*(uint8*)WBUFP((p),(pos))) |
---|
58 | #define WBUFW(p,pos) (*(uint16*)WBUFP((p),(pos))) |
---|
59 | #define WBUFL(p,pos) (*(uint32*)WBUFP((p),(pos))) |
---|
60 | |
---|
61 | #define TOB(n) ((uint8)((n)&UINT8_MAX)) |
---|
62 | #define TOW(n) ((uint16)((n)&UINT16_MAX)) |
---|
63 | #define TOL(n) ((uint32)((n)&UINT32_MAX)) |
---|
64 | |
---|
65 | |
---|
66 | // Struct declaration |
---|
67 | typedef int (*RecvFunc)(int fd); |
---|
68 | typedef int (*SendFunc)(int fd); |
---|
69 | typedef int (*ParseFunc)(int fd); |
---|
70 | |
---|
71 | struct socket_data |
---|
72 | { |
---|
73 | struct { |
---|
74 | unsigned char eof : 1; |
---|
75 | unsigned char server : 1; |
---|
76 | } flag; |
---|
77 | |
---|
78 | uint32 client_addr; // remote client address |
---|
79 | |
---|
80 | uint8 *rdata, *wdata; |
---|
81 | size_t max_rdata, max_wdata; |
---|
82 | size_t rdata_size, wdata_size; |
---|
83 | size_t rdata_pos; |
---|
84 | time_t rdata_tick; // time of last recv (for detecting timeouts); zero when timeout is disabled |
---|
85 | |
---|
86 | RecvFunc func_recv; |
---|
87 | SendFunc func_send; |
---|
88 | ParseFunc func_parse; |
---|
89 | |
---|
90 | void* session_data; // stores application-specific data related to the session |
---|
91 | }; |
---|
92 | |
---|
93 | |
---|
94 | // Data prototype declaration |
---|
95 | |
---|
96 | extern struct socket_data* session[FD_SETSIZE]; |
---|
97 | |
---|
98 | extern int fd_max; |
---|
99 | |
---|
100 | extern time_t last_tick; |
---|
101 | extern time_t stall_time; |
---|
102 | |
---|
103 | ////////////////////////////////// |
---|
104 | // some checking on sockets |
---|
105 | extern bool session_isValid(int fd); |
---|
106 | extern bool session_isActive(int fd); |
---|
107 | ////////////////////////////////// |
---|
108 | |
---|
109 | // Function prototype declaration |
---|
110 | |
---|
111 | int make_listen_bind(uint32 ip, uint16 port); |
---|
112 | int make_connection(uint32 ip, uint16 port); |
---|
113 | int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size); |
---|
114 | int realloc_writefifo(int fd, size_t addition); |
---|
115 | int WFIFOSET(int fd, size_t len); |
---|
116 | int RFIFOSKIP(int fd, size_t len); |
---|
117 | |
---|
118 | int do_sockets(int next); |
---|
119 | void do_close(int fd); |
---|
120 | void socket_init(void); |
---|
121 | void socket_final(void); |
---|
122 | |
---|
123 | extern void flush_fifo(int fd); |
---|
124 | extern void flush_fifos(void); |
---|
125 | extern void set_nonblocking(int fd, unsigned long yes); |
---|
126 | |
---|
127 | void set_defaultparse(ParseFunc defaultparse); |
---|
128 | |
---|
129 | // hostname/ip conversion functions |
---|
130 | uint32 host2ip(const char* hostname); |
---|
131 | const char* ip2str(uint32 ip, char ip_str[16]); |
---|
132 | uint32 str2ip(const char* ip_str); |
---|
133 | #define CONVIP(ip) ((ip)>>24)&0xFF,((ip)>>16)&0xFF,((ip)>>8)&0xFF,((ip)>>0)&0xFF |
---|
134 | uint16 ntows(uint16 netshort); |
---|
135 | |
---|
136 | int socket_getips(uint32* ips, int max); |
---|
137 | |
---|
138 | extern uint32 addr_[16]; // ip addresses of local host (host byte order) |
---|
139 | extern int naddr_; // # of ip addresses |
---|
140 | |
---|
141 | void set_eof(int fd); |
---|
142 | |
---|
143 | /// Use a shortlist of sockets instead of iterating all sessions for sockets |
---|
144 | /// that have data to send or need eof handling. |
---|
145 | /// Adapted to use a static array instead of a linked list. |
---|
146 | /// |
---|
147 | /// @author Buuyo-tama |
---|
148 | #define SEND_SHORTLIST |
---|
149 | |
---|
150 | #ifdef SEND_SHORTLIST |
---|
151 | struct send_shortlist_node { |
---|
152 | struct send_shortlist_node *next; // Next node in the linked list |
---|
153 | struct send_shortlist_node *prev; // Previous node in the linked list |
---|
154 | int fd; // FD that needs sending. |
---|
155 | }; |
---|
156 | |
---|
157 | // Add a fd to the shortlist so that it'll be recognized as a fd that needs |
---|
158 | // sending done on it. |
---|
159 | void send_shortlist_add_fd(int fd); |
---|
160 | // Do pending network sends (and eof handling) from the shortlist. |
---|
161 | void send_shortlist_do_sends(); |
---|
162 | #endif |
---|
163 | |
---|
164 | #endif /* _SOCKET_H_ */ |
---|