[1] | 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_ */ |
---|