tools/daemon/smud_connections.cpp
branchrefac-jit
changeset 2284 026da5437111
parent 2192 7602d7fb60d9
child 2288 15c77b21589a
     1.1 --- a/tools/daemon/smud_connections.cpp	Fri Jul 11 06:51:21 2008 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,404 +0,0 @@
     1.4 -#include "smud_connections.h"
     1.5 -#include "smud.h"
     1.6 -
     1.7 -ConnectionPool::ConnectionPool()
     1.8 -{
     1.9 -	pthread_mutex_init(&m_AddLock, NULL);
    1.10 -	m_timeOut = 1000;
    1.11 -}
    1.12 -
    1.13 -ConnectionPool::~ConnectionPool()
    1.14 -{
    1.15 -	pthread_mutex_destroy(&m_AddLock);
    1.16 -}
    1.17 -
    1.18 -void ConnectionPool::AddConnection( int fd )
    1.19 -{
    1.20 -	smud_connection *connection = new smud_connection(fd);
    1.21 -
    1.22 -	pthread_mutex_lock(&m_AddLock);
    1.23 -	m_AddQueue.push_back(connection);
    1.24 -	pthread_mutex_unlock(&m_AddLock);
    1.25 -
    1.26 -	printf("New Connection Added\n");
    1.27 -}
    1.28 -
    1.29 -void ConnectionPool::Process( bool *terminate )
    1.30 -{
    1.31 -	struct timespec ts_wait;
    1.32 -
    1.33 -	ts_wait.tv_sec = 0;
    1.34 -	ts_wait.tv_nsec = 50000000; /* 50ms */
    1.35 -
    1.36 -	std::list<smud_connection *>::iterator iter;
    1.37 -	smud_connection *con = NULL;
    1.38 -
    1.39 -	while (1)
    1.40 -	{
    1.41 -		if (*terminate)
    1.42 -		{
    1.43 -			return;
    1.44 -		}
    1.45 -
    1.46 -		iter = m_Links.begin();
    1.47 -
    1.48 -		QueryResult result = QueryResult_Continue;
    1.49 -		int pollReturn = 0;
    1.50 -
    1.51 -		/* Add all connections that want processing to the sets */
    1.52 -		while (iter != m_Links.end())
    1.53 -		{
    1.54 -			con = (smud_connection *)*iter;
    1.55 -
    1.56 -			pollReturn = poll(&(con->pollData), 1, 0);
    1.57 -
    1.58 -			if (pollReturn == -1)
    1.59 -			{
    1.60 -				//Something went badly wrong or the connection closed.
    1.61 -				result = QueryResult_Complete;
    1.62 -			}
    1.63 -			else if (pollReturn == 1)
    1.64 -			{
    1.65 -				//Poll returns the number of sockets available (which can only ever be 1)
    1.66 -				result = ProcessConnection(con);
    1.67 -			}
    1.68 -
    1.69 -			if (result == QueryResult_Complete)
    1.70 -			{
    1.71 -				iter = m_Links.erase(iter);
    1.72 -				closesocket(con->fd);
    1.73 -				delete con;
    1.74 -
    1.75 -				printf("Connection Completed!\n");
    1.76 -
    1.77 -				continue;
    1.78 -			}
    1.79 -
    1.80 -			iter++;
    1.81 -		}
    1.82 -
    1.83 -		/* Add new items to process */
    1.84 -
    1.85 -		iter = m_Links.end();
    1.86 -		pthread_mutex_lock(&m_AddLock);
    1.87 -		m_Links.splice(iter, m_AddQueue);
    1.88 -		pthread_mutex_unlock(&m_AddLock);
    1.89 -
    1.90 -		nanosleep(&ts_wait, NULL);
    1.91 -	}
    1.92 -}
    1.93 -
    1.94 -QueryResult ConnectionPool::ProcessConnection( smud_connection *con )
    1.95 -{
    1.96 -	switch (con->state)
    1.97 -	{
    1.98 -		case ConnectionState_ReadQueryHeader:
    1.99 -		{
   1.100 -			ReadQueryHeader(con);
   1.101 -			break;
   1.102 -		}
   1.103 -
   1.104 -		case ConnectionState_ReadQueryData:
   1.105 -		{
   1.106 -			ReadQueryContent(con);
   1.107 -			break;
   1.108 -		}
   1.109 -
   1.110 -		case ConnectionState_ReplyQuery:
   1.111 -		{
   1.112 -			ReplyQuery(con);
   1.113 -			break;
   1.114 -		}
   1.115 -
   1.116 -		case ConnectionState_SendingFiles:
   1.117 -		{
   1.118 -			SendFile(con);
   1.119 -			break;
   1.120 -		}
   1.121 -
   1.122 -		case ConnectionState_SendUnknownList:
   1.123 -		{
   1.124 -			SendUnknownList(con);
   1.125 -			break;
   1.126 -		}
   1.127 -
   1.128 -		case ConnectionState_Complete:
   1.129 -		{
   1.130 -			break;
   1.131 -		}
   1.132 -	}
   1.133 -
   1.134 -	if (con->state == ConnectionState_Complete)
   1.135 -	{
   1.136 -		printf("Ending connection because it marked itself as finished\n");
   1.137 -		return QueryResult_Complete;
   1.138 -	}
   1.139 -
   1.140 -	if (con->start + m_timeOut < time(NULL))
   1.141 -	{
   1.142 -		printf("Ending connection because it has passed maximum allowed time\n");
   1.143 -		return QueryResult_Complete;
   1.144 -	}
   1.145 -
   1.146 -	return QueryResult_Continue;
   1.147 -}
   1.148 -
   1.149 -void ConnectionPool::ReadQueryHeader( smud_connection *con )
   1.150 -{
   1.151 -	char data[11];
   1.152 -
   1.153 -	if (recv(con->fd, data, sizeof(data), 0) == -1)
   1.154 -	{
   1.155 -		if (errno != EAGAIN && errno != EWOULDBLOCK)
   1.156 -		{
   1.157 -			con->state = ConnectionState_Complete;
   1.158 -		}
   1.159 -
   1.160 -		return;
   1.161 -	}
   1.162 -
   1.163 -	if (data[0] != 'A' || data[1] != 'G')
   1.164 -	{
   1.165 -		con->state = ConnectionState_Complete;
   1.166 -		return;
   1.167 -	}
   1.168 -
   1.169 -	//Ignore the next 8 bytes for the moment. Versioning data is currently unused
   1.170 -	// uint16[4] - source version major/minor/something/rev
   1.171 -
   1.172 -	con->sentSums = data[10];
   1.173 -
   1.174 -	con->state = ConnectionState_ReadQueryData;
   1.175 -	printf("Query Header Read Complete, %i md5's expected\n", con->sentSums);
   1.176 -}
   1.177 -
   1.178 -void ConnectionPool::ReplyQuery(smud_connection *con)
   1.179 -{
   1.180 -	char data[12];
   1.181 -	data[0] = 'A';
   1.182 -	data[1] = 'G';
   1.183 -
   1.184 -	data[2] = (char)Update_Unknown; //unused versioning crap
   1.185 -	*(short *)&data[3] = 1;
   1.186 -	*(short *)&data[5] = 0;
   1.187 -	*(short *)&data[7] = 0;
   1.188 -	*(short *)&data[9] = 3;
   1.189 -
   1.190 -	data[11] = (char)con->sendCount;
   1.191 -
   1.192 -	if (send(con->fd, data, sizeof(data), 0) == -1)
   1.193 -	{
   1.194 -		if (errno != EAGAIN && errno != EWOULDBLOCK)
   1.195 -		{
   1.196 -			con->state = ConnectionState_Complete;
   1.197 -		}
   1.198 -
   1.199 -		return;
   1.200 -	}
   1.201 -	
   1.202 -	//Now we need more send sub functions for all the damn files. Geh.
   1.203 -	//Alternatively we could just send all at once here. Could make for a damn big query. 100k anyone?
   1.204 -
   1.205 -	con->state = ConnectionState_SendingFiles;
   1.206 -	printf("Query Reply Header Complete\n");
   1.207 -}
   1.208 -
   1.209 -void ConnectionPool::ReadQueryContent( smud_connection *con )
   1.210 -{
   1.211 -	char *data = new char[16*(con->sentSums)]();
   1.212 -
   1.213 -	if (recv(con->fd, data, 16*(con->sentSums), 0) == -1)
   1.214 -	{
   1.215 -		if (errno != EAGAIN && errno != EWOULDBLOCK)
   1.216 -		{
   1.217 -			con->state = ConnectionState_Complete;
   1.218 -		}
   1.219 -
   1.220 -		delete [] data;
   1.221 -		return;
   1.222 -	}
   1.223 -
   1.224 -	con->shouldSend = new MD5Status[con->sentSums]();
   1.225 -	con->fileLocation = new int[con->sentSums]();
   1.226 -	con->headerSent = new bool[con->sentSums]();
   1.227 -
   1.228 -	for (int i=0; i<con->sentSums; i++)
   1.229 -	{
   1.230 -		con->fileLocation[i] = -1;
   1.231 -		con->shouldSend[i] = GetMD5UpdateStatus(data + (16*i), con, i);
   1.232 -		
   1.233 -		if (con->shouldSend[i] == MD5Status_NeedsUpdate)
   1.234 -		{
   1.235 -			printf("File %i needs updating\n", i);
   1.236 -			con->sendCount++;
   1.237 -			con->headerSent[i] = false;
   1.238 -			continue;
   1.239 -		}
   1.240 -
   1.241 -		if (con->shouldSend[i] == MD5Status_Unknown)
   1.242 -		{
   1.243 -			printf("File %i is unknown\n", i);
   1.244 -			con->unknownCount++;
   1.245 -		}
   1.246 -	}
   1.247 -
   1.248 -	con->state = ConnectionState_ReplyQuery;
   1.249 -	con->pollData.events = POLLOUT;
   1.250 -	delete [] data;
   1.251 -	printf("Query Data Read Complete\n");
   1.252 -}
   1.253 -
   1.254 -MD5Status ConnectionPool::GetMD5UpdateStatus( const char *md5 , smud_connection *con, int fileNum)
   1.255 -{
   1.256 -	//Try find a file with this name in some directory.
   1.257 -	char path[100] = "./md5/";
   1.258 -	char temp[4];
   1.259 -	char md5String[33] = "";
   1.260 -
   1.261 -	for (int i=0; i<16; i++)
   1.262 -	{
   1.263 -		snprintf(temp, sizeof(temp), "%02x", (unsigned char)md5[i]);
   1.264 -		strcat(md5String, temp);
   1.265 -	}
   1.266 -
   1.267 -	strcat(path, md5String);
   1.268 -
   1.269 -	printf("checking for file \"%s\"\n", path);
   1.270 -	
   1.271 -	FILE *file = fopen(path, "r");
   1.272 -
   1.273 -	if (file == NULL)
   1.274 -	{
   1.275 -		printf("Couldn't find file!\n");
   1.276 -		return MD5Status_Unknown;
   1.277 -	}
   1.278 -
   1.279 -	char latestMD5[33];
   1.280 -	fgets(latestMD5, 33, file);
   1.281 -	printf("Latest md5 is: %s\n", latestMD5);
   1.282 -
   1.283 -	if (strcmp(latestMD5, md5String) == 0)
   1.284 -	{
   1.285 -		return MD5Status_Current;
   1.286 -	}
   1.287 -
   1.288 -	char filename[100];
   1.289 -	filename[0] = '\n';
   1.290 -
   1.291 -	while (filename[0] == '\n')
   1.292 -	{
   1.293 -		fgets(filename, sizeof(filename), file);
   1.294 -	}
   1.295 -
   1.296 -	if (filename[strlen(filename)-1] == '\n')
   1.297 -	{	
   1.298 -		filename[strlen(filename)-1] = '\0';
   1.299 -	}
   1.300 -
   1.301 -
   1.302 -
   1.303 -	printf("Filename is %s\n", filename);
   1.304 -
   1.305 -	//We now need to match this filename with one of our mmap'd files in memory and store it until send gets called.
   1.306 -	for (int i=0; i<NUM_FILES; i++)
   1.307 -	{
   1.308 -		if (strcmp(fileNames[i], filename) == 0)
   1.309 -		{
   1.310 -			con->fileLocation[fileNum] = i;
   1.311 -			printf("File %i mapped to local file %i\n", fileNum, i);
   1.312 -			return MD5Status_NeedsUpdate;
   1.313 -		}
   1.314 -	}
   1.315 -
   1.316 -	return MD5Status_Unknown;
   1.317 -}
   1.318 -
   1.319 -void ConnectionPool::SendFile( smud_connection *con )
   1.320 -{
   1.321 -	//Find the next file to send.
   1.322 -	while (con->currentFile < con->sentSums &&
   1.323 -			con->shouldSend[con->currentFile] != MD5Status_NeedsUpdate)
   1.324 -	{
   1.325 -		con->currentFile++;
   1.326 -	}
   1.327 -
   1.328 -	//All files have been sent.
   1.329 -	if (con->currentFile >= con->sentSums)
   1.330 -	{
   1.331 -		printf("All files sent!\n");
   1.332 -		con->state = ConnectionState_SendUnknownList;
   1.333 -		return;
   1.334 -	}
   1.335 -
   1.336 -	void *file = fileLocations[con->fileLocation[con->currentFile]];
   1.337 -	int filelength = fileLength[con->fileLocation[con->currentFile]];
   1.338 -
   1.339 -	printf("Sending file of length %i\n", filelength);
   1.340 -	printf("Current file index is: %i, maps to file index: %i\n", con->currentFile, con->fileLocation[con->currentFile]);
   1.341 -
   1.342 -	if (!con->headerSent[con->currentFile])
   1.343 -	{
   1.344 -		char buffer[5];
   1.345 -		buffer[0] = con->currentFile;
   1.346 -		*((int *)&buffer[1]) = filelength;
   1.347 -
   1.348 -		if (send(con->fd, buffer, 5, 0) == -1)
   1.349 -		{
   1.350 -			if (errno != EAGAIN && errno != EWOULDBLOCK)
   1.351 -			{
   1.352 -				con->state = ConnectionState_Complete;
   1.353 -			}
   1.354 -
   1.355 -			return;
   1.356 -		}
   1.357 -
   1.358 -		con->headerSent[con->currentFile] = true;
   1.359 -	}
   1.360 -
   1.361 -	if (send(con->fd, file, filelength, 0) == -1)
   1.362 -	{
   1.363 -		if (errno != EAGAIN && errno != EWOULDBLOCK)
   1.364 -		{
   1.365 -			con->state = ConnectionState_Complete;
   1.366 -		}
   1.367 -
   1.368 -		return;
   1.369 -	}
   1.370 -
   1.371 -	con->currentFile++;
   1.372 -	printf("Sent a file!: %s\n", fileNames[con->fileLocation[con->currentFile-1]]);
   1.373 -}
   1.374 -
   1.375 -void ConnectionPool::SendUnknownList( smud_connection *con )
   1.376 -{
   1.377 -	int size = con->unknownCount+1;
   1.378 -	char *packet = new char[size]();
   1.379 -
   1.380 -	packet[0] = con->unknownCount;
   1.381 -
   1.382 -	printf("%i Files are unknown\n", con->unknownCount);
   1.383 -
   1.384 -	int i=1;
   1.385 -
   1.386 -	for (int j=0; j<con->sentSums; j++)
   1.387 -	{
   1.388 -		if (con->shouldSend[j] == MD5Status_Unknown)
   1.389 -		{
   1.390 -			packet[i] = j;
   1.391 -			i++;
   1.392 -		}
   1.393 -	}
   1.394 -
   1.395 -	if (send(con->fd, packet, size, 0) == -1)
   1.396 -	{
   1.397 -		if (errno != EAGAIN && errno != EWOULDBLOCK)
   1.398 -		{
   1.399 -			con->state = ConnectionState_Complete;
   1.400 -		}
   1.401 -
   1.402 -		return;
   1.403 -	}
   1.404 -
   1.405 -	con->state = ConnectionState_Complete;
   1.406 -	printf("Unknown's Sent\n");
   1.407 -}