+ // Dispatch to worker
+ if( Client->CurrentRequest ) {
+ printf("Worker thread for client ID %i is busy\n", Client->ClientID);
+ return 1;
+ }
+
+ // Give to worker
+ Log_Debug("Server", "Message from Client %i (%p)", Client->ClientID, Client);
+ Client->CurrentRequest = hdr;
+ SDL_CondSignal(Client->WaitFlag);
+
+ return 0;
+}
+
+int Server_int_HandshakeClient(int Socket, struct sockaddr_in *addr, socklen_t addr_size)
+{
+ ENTER("iSocket paddr iaddr_size",
+ Socket, addr, addr_size);
+ unsigned short port = ntohs(addr->sin_port);
+ char addrstr[4*8+8+1];
+ getnameinfo((struct sockaddr*)addr, addr_size, addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
+ Log_Debug("Server", "Client connection %s:%i", addrstr, port);
+
+ // Perform handshake
+ tRequestAuthHdr authhdr;
+ size_t len = recv(Socket, &authhdr, sizeof(authhdr), 0);
+ if( len != sizeof(authhdr) ) {
+ // Some form of error?
+ Log_Warning("Server", "Client auth block bad size (%i != exp %i)",
+ len, sizeof(authhdr));
+ LEAVE('i', 1);
+ return 1;
+ }
+
+ LOG("authhdr.pid = %i", authhdr.pid);
+ tClient *client = Server_GetClient(authhdr.pid);
+ if( authhdr.pid == 0 ) {
+ // Allocate PID and client structure/thread
+ client->Socket = Socket;
+ authhdr.pid = client->ClientID;
+ }
+ else {
+ Log_Debug("Server", "Client assumed PID %i", authhdr.pid);
+
+ // Get client structure and make sure it's unused
+ // - Auth token / verifcation?
+ if( !client ) {
+ Log_Warning("Server", "Can't allocate a client struct for %s:%i",
+ addrstr, port);
+ LEAVE('i', 1);
+ return 1;
+ }
+ if( client->Socket != 0 ) {
+ Log_Warning("Server", "Client (%i)%p owned by FD%i but %s:%i tried to use it",
+ authhdr.pid, client, addrstr, port);
+ LEAVE('i', 1);
+ return 1;
+ }
+
+ client->Socket = Socket;
+ }
+
+ LOG("Sending auth reply");
+ len = send(Socket, (void*)&authhdr, sizeof(authhdr), 0);
+ if( len != sizeof(authhdr) ) {
+ // Ok, this is an error
+ perror("Sending auth reply");
+ LEAVE('i', 1);
+ return 1;
+ }
+
+ // All done, client thread should be watching now
+
+ LEAVE('i', 0);
+ return 0;
+}
+
+void Server_int_RemoveClient(tClient *Client)
+{
+ // Trigger the thread to kill itself
+ Threads_int_Terminate( Threads_GetThread(Client->ClientID) );
+ Client->ClientID = 0;
+ close(Client->Socket);
+}
+
+#endif
+
+int Server_ListenThread(void *Unused)
+{