2 * Copyright (C) Volition, Inc. 2005. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on the
11 //Validate tracker user class
15 #include <arpa/inet.h>
16 #include <netinet/in.h>
29 udp_packet_header PacketHeader;
30 validate_id_request *ValidIDReq;
35 SOCKADDR_IN rtrackaddr;
43 int MissionValidState;
44 int MissionValidFirstSent;
45 int MissionValidLastSent;
47 // squad war validation
48 int SquadWarValidState;
49 int SquadWarFirstSent;
53 squad_war_response SquadWarValidateResponse;
55 int InitValidateClient(void)
61 ValidState = VALID_STATE_IDLE;
63 MissionValidFirstSent = 0;
64 MissionValidLastSent = 0;
65 MissionValidState = VALID_STATE_IDLE;
67 SquadWarFirstSent = 0;
69 SquadWarValidState = VALID_STATE_IDLE;
72 validsock = socket(AF_INET,SOCK_DGRAM,0);
73 if ( validsock == INVALID_SOCKET )
75 printf("Unable to open a socket.\n");
80 memset( &sockaddr, 0, sizeof(SOCKADDR_IN) );
81 sockaddr.sin_family = AF_INET;
82 sockaddr.sin_addr.s_addr = INADDR_ANY;
83 sockaddr.sin_port = 0;
86 if (SOCKET_ERROR==bind(validsock, (SOCKADDR*)&sockaddr, sizeof (sockaddr)))
88 printf("Unable to bind a socket.\n");
89 printf("WSAGetLastError() returned %d.\n",WSAGetLastError());
94 rtrackaddr.sin_family = AF_INET;
95 iaddr = inet_addr( Multi_options_g.user_tracker_ip );
96 if ( iaddr == INADDR_NONE ) {
98 he = gethostbyname( Multi_options_g.user_tracker_ip );
103 // try and resolve by address
104 unsigned int n_order = inet_addr(Multi_user_tracker_ip_address);
105 he = gethostbyaddr((char*)&n_order,4,PF_INET);
112 memcpy(&iaddr, he->h_addr_list[0],4);
115 memcpy(&rtrackaddr.sin_addr.s_addr, &iaddr, 4);
116 rtrackaddr.sin_port = htons(REGPORT);
122 //Call with a valid struct to validate a user
123 //Call with NULL to poll
126 // -3 Still waiting (returned if we were waiting for a tracker response and ValidateUser was called with a non-NULL value
127 // -2 Timeout waiting for tracker to respond
129 // 0 Still waiting for response from tracker/Idle
131 int ValidateUser(validate_id_request *valid_id, char *trackerid)
138 case VALID_STATE_IDLE:
141 case VALID_STATE_WAITING:
144 case VALID_STATE_VALID:
145 ValidState = VALID_STATE_IDLE;
148 case VALID_STATE_INVALID:
149 ValidState = VALID_STATE_IDLE;
151 case VALID_STATE_TIMEOUT:
152 ValidState = VALID_STATE_IDLE;
159 if(ValidState==VALID_STATE_IDLE)
161 //First, flush the input buffer for the socket
169 FD_SET(Unreliable_socket, &read_fds);
172 while(SELECT(0,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_VALIDATION))
174 while(SELECT(Unreliable_socket+1,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_VALIDATION))
178 SOCKADDR_IN fromaddr;
180 udp_packet_header inpacket;
181 addrsize = sizeof(SOCKADDR_IN);
182 RECVFROM(Unreliable_socket, (char *)&inpacket,sizeof(udp_packet_header),0,(SOCKADDR *)&fromaddr,&addrsize, PSNET_TYPE_VALIDATION);
184 Psztracker_id = trackerid;
186 //Build the request packet
187 PacketHeader.type = UNT_LOGIN_AUTH_REQUEST;
188 PacketHeader.len = PACKED_HEADER_ONLY_SIZE+sizeof(validate_id_request);
189 ValidIDReq=(validate_id_request *)&PacketHeader.data;
190 strcpy(ValidIDReq->login,valid_id->login);
191 strcpy(ValidIDReq->password,valid_id->password);
193 SENDTO(Unreliable_socket, (char *)&PacketHeader,PacketHeader.len,0,(SOCKADDR *)&rtrackaddr,sizeof(SOCKADDR), PSNET_TYPE_VALIDATION);
194 ValidState = VALID_STATE_WAITING;
195 ValidFirstSent = timer_get_milliseconds();
196 ValidLastSent = timer_get_milliseconds();
212 PSNET_TOP_LAYER_PROCESS();
218 FD_SET(Unreliable_socket, &read_fds);
221 if(SELECT(0,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_VALIDATION)){
223 if(SELECT(Unreliable_socket+1,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_VALIDATION)){
227 SOCKADDR_IN fromaddr;
229 udp_packet_header inpacket;
230 addrsize = sizeof(SOCKADDR_IN);
232 bytesin = RECVFROM(Unreliable_socket, (char *)&inpacket, sizeof(udp_packet_header),0,(SOCKADDR *)&fromaddr,&addrsize, PSNET_TYPE_VALIDATION);
234 int wserr=WSAGetLastError();
235 printf("recvfrom() failure. WSAGetLastError() returned %d\n",wserr);
239 FD_SET(Unreliable_socket, &read_fds);
241 // decrease packet size by 1
244 //Check to make sure the packets ok
245 if(bytesin==inpacket.len){
246 switch(inpacket.type)
248 case UNT_LOGIN_NO_AUTH:
249 if(ValidState == VALID_STATE_WAITING)
251 ValidState = VALID_STATE_INVALID;
254 case UNT_LOGIN_AUTHENTICATED:
255 if(ValidState == VALID_STATE_WAITING)
257 ValidState = VALID_STATE_VALID;
258 strncpy(Psztracker_id, (const char *)&inpacket.data, TRACKER_ID_LEN);
261 // old - this is a Freespace 1 packet type
262 case UNT_VALID_FS_MSN_RSP:
266 // fs2 mission validation response
267 case UNT_VALID_FS2_MSN_RSP:
268 if(MissionValidState == VALID_STATE_WAITING){
269 if(inpacket.code==2){
270 MissionValidState = VALID_STATE_VALID;
272 MissionValidState = VALID_STATE_INVALID;
277 // fs2 squad war validation response
278 case UNT_VALID_SW_MSN_RSP:
279 if(SquadWarValidState == VALID_STATE_WAITING){
281 SDL_assert((bytesin - PACKED_HEADER_ONLY_SIZE) == sizeof(squad_war_response));
282 if((bytesin - PACKED_HEADER_ONLY_SIZE) == sizeof(squad_war_response)){
283 memset(&SquadWarValidateResponse, 0, sizeof(squad_war_response));
284 memcpy(&SquadWarValidateResponse, inpacket.data, sizeof(squad_war_response));
286 // now check to see if we're good
287 if(SquadWarValidateResponse.accepted){
288 SquadWarValidState = VALID_STATE_VALID;
290 SquadWarValidState = VALID_STATE_INVALID;
293 SquadWarValidState = VALID_STATE_INVALID;
298 case UNT_CONTROL_VALIDATION:
306 AckValidServer(inpacket.sig);
310 if(ValidState == VALID_STATE_WAITING)
312 if((timer_get_milliseconds()-ValidFirstSent)>=PILOT_REQ_TIMEOUT)
314 ValidState = VALID_STATE_TIMEOUT;
317 else if((timer_get_milliseconds()-ValidLastSent)>=PILOT_REQ_RESEND_TIME)
320 SENDTO(Unreliable_socket, (char *)&PacketHeader, PacketHeader.len, 0, (SOCKADDR *)&rtrackaddr, sizeof(SOCKADDR), PSNET_TYPE_VALIDATION);
321 ValidLastSent = timer_get_milliseconds();
327 //Send an ACK to the server
328 void AckValidServer(unsigned int sig)
330 udp_packet_header ack_pack;
332 ack_pack.type = UNT_CONTROL;
334 ack_pack.code = CMD_CLIENT_RECEIVED;
335 ack_pack.len = PACKED_HEADER_ONLY_SIZE;
337 SENDTO(Unreliable_socket, (char *)&ack_pack,PACKED_HEADER_ONLY_SIZE,0,(SOCKADDR *)&rtrackaddr,sizeof(SOCKADDR_IN), PSNET_TYPE_VALIDATION);
340 // call with a valid struct to validate a mission
341 // call with NULL to poll
344 // -3 Still waiting (returned if we were waiting for a tracker response and ValidateMission was called with a non-NULL value
345 // -2 Timeout waiting for tracker to respond
347 // 0 Still waiting for response from tracker/Idle
349 int ValidateMission(vmt_validate_mission_req_struct *valid_msn)
354 switch(MissionValidState)
356 case VALID_STATE_IDLE:
359 case VALID_STATE_WAITING:
362 case VALID_STATE_VALID:
363 MissionValidState = VALID_STATE_IDLE;
366 case VALID_STATE_INVALID:
367 MissionValidState = VALID_STATE_IDLE;
369 case VALID_STATE_TIMEOUT:
370 MissionValidState = VALID_STATE_IDLE;
377 if(MissionValidState==VALID_STATE_IDLE)
379 //First, flush the input buffer for the socket
387 FD_SET(Unreliable_socket, &read_fds);
390 while(SELECT(0,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_VALIDATION))
392 while(SELECT(Unreliable_socket+1,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_VALIDATION))
396 SOCKADDR_IN fromaddr;
398 udp_packet_header inpacket;
399 addrsize = sizeof(SOCKADDR_IN);
400 RECVFROM(Unreliable_socket, (char *)&inpacket,sizeof(udp_packet_header),0,(SOCKADDR *)&fromaddr,&addrsize, PSNET_TYPE_VALIDATION);
402 FD_SET(Unreliable_socket, &read_fds);
404 //only send the header, the checksum and the string length plus the null
405 PacketHeader.type = UNT_VALID_FS2_MSN_REQ;
406 PacketHeader.len = (short)(PACKED_HEADER_ONLY_SIZE + sizeof(int)+1+strlen(valid_msn->file_name));
407 memcpy(PacketHeader.data,valid_msn,PacketHeader.len-PACKED_HEADER_ONLY_SIZE);
408 SENDTO(Unreliable_socket, (char *)&PacketHeader,PacketHeader.len,0,(SOCKADDR *)&rtrackaddr,sizeof(SOCKADDR), PSNET_TYPE_VALIDATION);
409 MissionValidState = VALID_STATE_WAITING;
410 MissionValidFirstSent = timer_get_milliseconds();
411 MissionValidLastSent = timer_get_milliseconds();
421 // query the usertracker to validate a squad war match
422 // call with a valid struct to validate a mission
423 // call with NULL to poll
426 // -3 Still waiting (returned if we were waiting for a tracker response and ValidateSquadWae was called with a non-NULL value
427 // -2 Timeout waiting for tracker to respond
429 // 0 Still waiting for response from tracker/Idle
431 int ValidateSquadWar(squad_war_request *sw_req, squad_war_response *sw_resp)
435 switch(SquadWarValidState){
436 case VALID_STATE_IDLE:
439 case VALID_STATE_WAITING:
443 // fill in the response
444 case VALID_STATE_VALID:
445 SquadWarValidState = VALID_STATE_IDLE;
447 memcpy(sw_resp, &SquadWarValidateResponse, sizeof(squad_war_response));
451 // fill in the response
452 case VALID_STATE_INVALID:
453 SquadWarValidState = VALID_STATE_IDLE;
455 memcpy(sw_resp, &SquadWarValidateResponse, sizeof(squad_war_response));
459 case VALID_STATE_TIMEOUT:
460 SquadWarValidState = VALID_STATE_IDLE;
465 if(SquadWarValidState==VALID_STATE_IDLE){
466 // First, flush the input buffer for the socket
474 FD_SET(Unreliable_socket, &read_fds);
477 while(SELECT(0,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_VALIDATION)){
479 while(SELECT(Unreliable_socket+1,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_VALIDATION)){
482 SOCKADDR_IN fromaddr;
484 udp_packet_header inpacket;
485 addrsize = sizeof(SOCKADDR_IN);
486 RECVFROM(Unreliable_socket, (char *)&inpacket,sizeof(udp_packet_header),0,(SOCKADDR *)&fromaddr,&addrsize, PSNET_TYPE_VALIDATION);
488 FD_SET(Unreliable_socket, &read_fds);
490 // only send the header, the checksum and the string length plus the null
491 PacketHeader.type = UNT_VALID_SW_MSN_REQ;
492 PacketHeader.len = (short)(PACKED_HEADER_ONLY_SIZE + sizeof(squad_war_request));
493 memcpy(PacketHeader.data, sw_req, PacketHeader.len-PACKED_HEADER_ONLY_SIZE);
494 SENDTO(Unreliable_socket, (char *)&PacketHeader, PacketHeader.len, 0, (SOCKADDR *)&rtrackaddr, sizeof(SOCKADDR), PSNET_TYPE_VALIDATION);
495 SquadWarValidState = VALID_STATE_WAITING;
496 SquadWarFirstSent = timer_get_milliseconds();
497 SquadWarLastSent = timer_get_milliseconds();