summaryrefslogtreecommitdiff
path: root/core/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/network.c')
-rw-r--r--core/network.c92
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. */
60static 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 */
64int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length) 61int 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. */
74static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length) 71static 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
92static packet_handler_callback packethandlers[256] = {0}; 89void networking_registerhandler(Networking_Core * net, uint8_t byte, packet_handler_callback cb, void * object)
93
94void 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
99void networking_poll() 95void 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 110uint8_t at_startup_ran;
115 bind to ip and port 111static 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 */
120int 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
129static 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 */
143Networking_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 */
184void shutdown_networking(void) 204void 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