diff options
Diffstat (limited to 'core/network.c')
-rw-r--r-- | core/network.c | 92 |
1 files changed, 56 insertions, 36 deletions
diff --git a/core/network.c b/core/network.c index 1977ce38..684a4227 100644 --- a/core/network.c +++ b/core/network.c | |||
@@ -56,12 +56,9 @@ uint32_t random_int(void) | |||
56 | #endif | 56 | #endif |
57 | } | 57 | } |
58 | 58 | ||
59 | /* our UDP socket, a global variable. */ | ||
60 | static int sock; | ||
61 | |||
62 | /* Basic network functions: | 59 | /* Basic network functions: |
63 | Function to send packet(data) of length length to ip_port */ | 60 | Function to send packet(data) of length length to ip_port */ |
64 | int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length) | 61 | int sendpacket(int sock, IP_Port ip_port, uint8_t *data, uint32_t length) |
65 | { | 62 | { |
66 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; | 63 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; |
67 | return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); | 64 | return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); |
@@ -71,7 +68,7 @@ int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length) | |||
71 | the packet data into data | 68 | the packet data into data |
72 | the packet length into length. | 69 | the packet length into length. |
73 | dump all empty packets. */ | 70 | dump all empty packets. */ |
74 | static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length) | 71 | static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) |
75 | { | 72 | { |
76 | ADDR addr; | 73 | ADDR addr; |
77 | #ifdef WIN32 | 74 | #ifdef WIN32 |
@@ -89,36 +86,32 @@ static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length) | |||
89 | return 0; | 86 | return 0; |
90 | } | 87 | } |
91 | 88 | ||
92 | static packet_handler_callback packethandlers[256] = {0}; | 89 | void networking_registerhandler(Networking_Core * net, uint8_t byte, packet_handler_callback cb, void * object) |
93 | |||
94 | void networking_registerhandler(uint8_t byte, packet_handler_callback cb) | ||
95 | { | 90 | { |
96 | packethandlers[byte] = cb; | 91 | net->packethandlers[byte].function = cb; |
92 | net->packethandlers[byte].object = object; | ||
97 | } | 93 | } |
98 | 94 | ||
99 | void networking_poll() | 95 | void networking_poll(Networking_Core * net) |
100 | { | 96 | { |
101 | IP_Port ip_port; | 97 | IP_Port ip_port; |
102 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 98 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
103 | uint32_t length; | 99 | uint32_t length; |
104 | 100 | ||
105 | while (receivepacket(&ip_port, data, &length) != -1) { | 101 | while (receivepacket(net->sock, &ip_port, data, &length) != -1) { |
106 | if (length < 1) continue; | 102 | if (length < 1) continue; |
107 | 103 | ||
108 | if (!packethandlers[data[0]]) continue; | 104 | if (!(net->packethandlers[data[0]].function)) continue; |
109 | 105 | ||
110 | packethandlers[data[0]](ip_port, data, length); | 106 | net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length); |
111 | } | 107 | } |
112 | } | 108 | } |
113 | 109 | ||
114 | /* initialize networking | 110 | uint8_t at_startup_ran; |
115 | bind to ip and port | 111 | static void at_startup(void) |
116 | ip must be in network order EX: 127.0.0.1 = (7F000001) | ||
117 | port is in host byte order (this means don't worry about it) | ||
118 | returns 0 if no problems | ||
119 | returns -1 if there are problems */ | ||
120 | int init_networking(IP ip, uint16_t port) | ||
121 | { | 112 | { |
113 | if (at_startup_ran != 0) | ||
114 | return; | ||
122 | #ifdef WIN32 | 115 | #ifdef WIN32 |
123 | WSADATA wsaData; | 116 | WSADATA wsaData; |
124 | 117 | ||
@@ -128,21 +121,48 @@ int init_networking(IP ip, uint16_t port) | |||
128 | #else | 121 | #else |
129 | srandom((uint32_t)current_time()); | 122 | srandom((uint32_t)current_time()); |
130 | #endif | 123 | #endif |
131 | srand((uint32_t)current_time()); | 124 | srand((uint32_t)current_time()); |
125 | at_startup_ran = 1; | ||
126 | } | ||
127 | |||
128 | /* TODO: put this somewhere | ||
129 | static void at_shutdown(void) | ||
130 | { | ||
131 | #ifdef WIN32 | ||
132 | WSACleanup(); | ||
133 | #endif | ||
134 | } | ||
135 | */ | ||
132 | 136 | ||
137 | /* initialize networking | ||
138 | bind to ip and port | ||
139 | ip must be in network order EX: 127.0.0.1 = (7F000001) | ||
140 | port is in host byte order (this means don't worry about it) | ||
141 | returns Networking_Core object if no problems | ||
142 | returns NULL if there are problems */ | ||
143 | Networking_Core * new_networking(IP ip, uint16_t port) | ||
144 | { | ||
145 | at_startup(); | ||
133 | /* initialize our socket */ | 146 | /* initialize our socket */ |
134 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | 147 | Networking_Core * temp = calloc(1, sizeof(Networking_Core)); |
148 | if (temp == NULL) | ||
149 | return NULL; | ||
150 | temp->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||
135 | 151 | ||
136 | /* Check for socket error */ | 152 | /* Check for socket error */ |
137 | #ifdef WIN32 | 153 | #ifdef WIN32 |
138 | 154 | ||
139 | if (sock == INVALID_SOCKET) /* MSDN recommends this */ | 155 | if (temp->sock == INVALID_SOCKET) { /* MSDN recommends this */ |
140 | return -1; | 156 | free(temp); |
157 | return NULL; | ||
158 | } | ||
141 | 159 | ||
142 | #else | 160 | #else |
143 | 161 | ||
144 | if (sock < 0) | 162 | if (temp->sock < 0) { |
145 | return -1; | 163 | free(temp); |
164 | return NULL; | ||
165 | } | ||
146 | 166 | ||
147 | #endif | 167 | #endif |
148 | 168 | ||
@@ -161,34 +181,34 @@ int init_networking(IP ip, uint16_t port) | |||
161 | 181 | ||
162 | /* Enable broadcast on socket */ | 182 | /* Enable broadcast on socket */ |
163 | int broadcast = 1; | 183 | int broadcast = 1; |
164 | setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); | 184 | setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); |
165 | 185 | ||
166 | /* Set socket nonblocking */ | 186 | /* Set socket nonblocking */ |
167 | #ifdef WIN32 | 187 | #ifdef WIN32 |
168 | /* I think this works for windows */ | 188 | /* I think this works for windows */ |
169 | u_long mode = 1; | 189 | u_long mode = 1; |
170 | /* ioctl(sock, FIONBIO, &mode); */ | 190 | /* ioctl(sock, FIONBIO, &mode); */ |
171 | ioctlsocket(sock, FIONBIO, &mode); | 191 | ioctlsocket(temp->sock, FIONBIO, &mode); |
172 | #else | 192 | #else |
173 | fcntl(sock, F_SETFL, O_NONBLOCK, 1); | 193 | fcntl(temp->sock, F_SETFL, O_NONBLOCK, 1); |
174 | #endif | 194 | #endif |
175 | 195 | ||
176 | /* Bind our socket to port PORT and address 0.0.0.0 */ | 196 | /* Bind our socket to port PORT and address 0.0.0.0 */ |
177 | ADDR addr = {AF_INET, htons(port), ip}; | 197 | ADDR addr = {AF_INET, htons(port), ip}; |
178 | bind(sock, (struct sockaddr *)&addr, sizeof(addr)); | 198 | bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr)); |
179 | 199 | temp_net = temp; | |
180 | return 0; | 200 | return temp; |
181 | } | 201 | } |
182 | 202 | ||
183 | /* function to cleanup networking stuff */ | 203 | /* function to cleanup networking stuff */ |
184 | void shutdown_networking(void) | 204 | void kill_networking(Networking_Core * net) |
185 | { | 205 | { |
186 | #ifdef WIN32 | 206 | #ifdef WIN32 |
187 | closesocket(sock); | 207 | closesocket(net->sock); |
188 | WSACleanup(); | ||
189 | #else | 208 | #else |
190 | close(sock); | 209 | close(net->sock); |
191 | #endif | 210 | #endif |
211 | free(net); | ||
192 | return; | 212 | return; |
193 | } | 213 | } |
194 | 214 | ||