Пример #1
0
/*
** get data from the client and return it
** run in a child process that was forked off from the main process.
*/
void process(int sock)
{
	char buf[XIA_MAXBUF + 1];
	int n;
	pid_t pid = getpid();

	fd_set fds;
	FD_ZERO(&fds);
	FD_SET(sock, &fds);

#ifdef USE_SELECT
	struct timeval tv;
	tv.tv_sec = WAIT_FOR_DATA;
	tv.tv_usec = 0;
#endif
   	while (1) {
		memset(buf, 0, sizeof(buf));
#ifdef USE_SELECT
		tv.tv_sec = WAIT_FOR_DATA;
		tv.tv_usec = 0;
		 if ((n = Xselect(sock + 1, &fds, NULL, NULL, &tv)) < 0) {
			 warn("%5d Select failed, closing...\n", pid);
			 break;

		 } else if (n == 0) {
			 // we timed out, close the socket
			 say("%5d timed out on recv\n", pid);
			 break;
		 } else if (!FD_ISSET(sock, &fds)) {
			 // this shouldn't happen!
			 die(-4, "something is really wrong, exiting\n");
		 }
#endif

		if ((n = Xrecv(sock, buf, sizeof(buf), 0)) < 0) {
			warn("Recv error on socket %d, closing connection\n", pid);
			break;
		} else if (n == 0) {
			warn("%d client closed the connection\n", pid);
			break;
		}

		say("%5d received %d bytes\n", pid, n);

		if ((n = Xsend(sock, buf, n, 0)) < 0) {
			warn("%5d send error\n", pid);
			break;
		}

		say("%5d sent %d bytes\n", pid, n);
   	}
	say("%5d closing\n", pid);
	Xclose(sock);
}
Пример #2
0
int getChunkCount(int sock, char *reply, int sz)
{
	int n;

	if ((n = Xrecv(sock, reply, sz, 0))  < 0) {
		Xclose(sock);
		 die(-1, "Unable to communicate with the server\n");
	}

	if (strncmp(reply, "OK:", 3) != 0) {
		die(-1, "%s\n", reply);
	}

	reply[n] = 0;

	return n;
}
Пример #3
0
int main(int argc, char **argv)
{
	struct addrinfo *ai;
	sockaddr_x *sa;
	int seq = 0;

// FIXME: put signal handlers back into code once Xselect is working
//	signal(SIGINT, handler);
//	signal(SIGTERM, handler);
	getConfig(argc, argv);

	if (Xgetaddrinfo(NAME, NULL, NULL, &ai) < 0)
		die("Unable to lookup address for  %s\n", NAME);
	sa = (sockaddr_x*)ai->ai_addr;

	if ((sock = Xsocket(AF_XIA, SOCK_STREAM, 0)) < 0)
		die("Unable to create a socket\n");

	say("Opening firehose: %s\n", NAME);
	if (Xconnect(sock, (struct sockaddr*)sa, sizeof(sockaddr_x)) < 0) {
		Xclose(sock);
		die("Unable to connect to %s\n", NAME);
	}

	// tell firehose how many packets we expect
	if (Xsend(sock, &fhc, sizeof(fhc), 0) < 0) {
		Xclose(sock);
		die("Unable to send config information to the firehose\n");
	}

	int count = 0;
	char  *buf = (char *)malloc(pktSize);

	while (!timetodie) {
		int n;
		fd_set fds;
		FD_ZERO(&fds);
		FD_SET(sock, &fds);

		struct timeval tv;
		tv.tv_sec = 2;
		tv.tv_usec = 0;

		if ((n = Xselect(sock + 1, &fds, NULL, NULL, &tv)) < 0) {
			printf("select failed\n");
			break;

		} else if (n == 0) {
			printf("recv timeout\n");
			break;
		} else if (!FD_ISSET(sock, &fds)) {
			// this shouldn't happen!
			printf("something is really wrong, exiting\n");
			break;
		}

		int rc = Xrecv(sock, buf, sizeof(buf), 0);
		if (rc < 0)
			die("Receive failure\n");
		memcpy(&seq, buf, sizeof(int));

		say("expecting %d, got %d", count, seq);
		if (count == seq)
			say("\n");
		else
			say(" lost %d\n", seq - count);
		count++;
		if (count == numPkts)
			break;
		if (delay)
			usleep(delay);
	}

	seq++;
	if (count != seq)
		printf("lost %d packets, received %d, expected %d\n", seq - count, count, seq); 
	else
		printf("success!\n");
	Xclose(sock);
}
Пример #4
0
void *recvCmd (void *socketid)
{
	int i, n, count = 0;
	ChunkInfo *info = NULL;
	char command[XIA_MAXBUF];
	char reply[XIA_MAXBUF];
	int sock = *((int*)socketid);
	char *fname;
	
	//ChunkContext contains size, ttl, policy, and contextID which for now is PID
	ChunkContext *ctx = XallocCacheSlice(POLICY_FIFO|POLICY_REMOVE_ON_EXIT, 0, 20000000);
	if (ctx == NULL)
		die(-2, "Unable to initilize the chunking system\n");

	while (1) {
		say("waiting for server command\n");
		memset(command, '\0', strlen(command));
		memset(reply, '\0', strlen(reply));
		if ((n = Xrecv(sock, command, 1024, 0))  < 0) {
			warn("socket error while waiting for data, closing connection\n");
			break;
		}
		//Sender does the chunking and then should start the sending commands
		if (strncmp(command, "get", 3) == 0) {
			fname = &command[4];
			say("Server requested file %s\n", fname);

			if (info) {
				// clean up the existing chunks first
			}
		
			info = NULL;
			count = 0;
			
			say("chunking file %s\n", fname);
			
			//Chunking is done by the XputFile which itself uses XputChunk, and fills out the info
			if ((count = XputFile(ctx, fname, CHUNKSIZE, &info)) < 0) {
				warn("unable to serve the file: %s\n", fname);
				sprintf(reply, "FAIL: File (%s) not found", fname);

			} else {
				sprintf(reply, "OK: %d", count);
			}
			say("%s\n", reply);
			
			
			//Just tells the receiver how many chunks it should expect.
			if (Xsend(sock, reply, strlen(reply), 0) < 0) {
				warn("unable to send reply to client\n");
				break;
			}
		//Sending the blocks cids
		} else if (strncmp(command, "block", 5) == 0) {
			char *start = &command[6];
			char *end = strchr(start, ':');
			if (!end) {
				// we have an invalid command, return error to client
				sprintf(reply, "FAIL: invalid block command");
			} else {
				*end = 0;
				end++;
				// FIXME: clean up naming, e is now a count
				int s = atoi(start);
				int e = s + atoi(end);
				strcpy(reply, "OK:");
				for(i = s; i < e && i < count; i++) {
					strcat(reply, " ");
					strcat(reply, info[i].cid);
				}
			}
			printf("%s\n", reply);
			if (Xsend(sock, reply, strlen(reply), 0) < 0) {
				warn("unable to send reply to client\n");
				break;
			}

		} else if (strncmp(command, "done", 4) == 0) {
			say("done sending file: removing the chunks from the cache\n");
			for (int i = 0; i < count; i++)
				XremoveChunk(ctx, info[i].cid);
			XfreeChunkInfo(info);
			info = NULL;
			count = 0;
			break;
		
		}
		else {
			sprintf(reply, "FAIL: invalid command (%s)\n", command);
			warn(reply);
			if (Xsend(sock, reply, strlen(reply), 0) < 0) {
				warn("unable to send reply to client\n");
				break;
			}
		}
	}
	
	if (info)
		XfreeChunkInfo(info);
	XfreeCacheSlice(ctx);
	return (void *)1;
}
Пример #5
0
/**
* @brief Initiate an XSSL connection with server.
*
* @param xssl
*
* @return 1 on success, <1 on failure
*/
int XSSL_connect(XSSL *xssl) {

	char buf[XIA_MAXBUF];
	int n;

	/* Send CLIENT HELLO */
	sprintf(buf, "CLIENT HELLO");
	if ((n = Xsend(xssl->sockfd, buf, strlen(buf), 0)) != strlen(buf)) {
		ERROR("ERROR sending CLIENT HELLO");
		return 0;
	}

	/* Wait for SERVER HELLO */
	// Receive public key + temporary public key signed by server's long-term private key
	// Continue receiving until we see "SERVER DONE"
	int offset = 0;
	while ( offset < 11 || strcmp("SERVER DONE", &buf[offset-11]) != 0 ) {
		n = Xrecv(xssl->sockfd, &buf[offset], sizeof(buf)-offset, 0);
		if (n < 0) {
			ERROR("ERROR receiving SERVER HELLO");
			return n;
		}
		if (n == 0) {
			ERROR("ERROR: server closed connection during SERVER HELLO");
			return n;
		}

		offset += n;
	}

	/* Parse public keys from SERVER HELLO */
	offset = strlen("SERVER HELLO");
	char *keys = &buf[offset];  // start of signed portion of message

	uint32_t *keybufsizeptr = (uint32_t*)&buf[offset];
	uint32_t keybufsize = *keybufsizeptr; // TODO: error checking here
	offset += sizeof(uint32_t);
	RSA *pubkey = deserialize_rsa_pub_key(&buf[offset], keybufsize);
	offset += keybufsize;

	uint32_t *tempkeybufsizeptr = (uint32_t*)&buf[offset];
	uint32_t tempkeybufsize = *tempkeybufsizeptr;
	offset += sizeof(uint32_t);
	RSA *sessionPubkey = deserialize_rsa_pub_key(&buf[offset], tempkeybufsize);
	offset += tempkeybufsize;

	uint32_t *siglenptr = (uint32_t*)&buf[offset];
	uint32_t siglen = *siglenptr;
	offset += sizeof(uint32_t);
	char* sig = &buf[offset];
	offset += siglen;
	DBGF("Received keys:\n\tkeylen: %d\n\ttempkeylen: %d\n\tsiglen: %d", keybufsize, tempkeybufsize, siglen);

	/* Verify two things:
	 *	1) hash(key) == SID so we trust the signature
	 *	2) verify the sig so we trust the temp key
	 */
	sockaddr_x *sa = (sockaddr_x*)malloc(sizeof(sockaddr_x));
	socklen_t len = sizeof(sockaddr_x);
	if (Xgetpeername(xssl->sockfd, (struct sockaddr*)sa, &len) < 0) {
		ERRORF("Error in Xgetpeername on socket %d: %s", xssl->sockfd, strerror(errno));
		return 0;
	}	
	Graph g(sa);
	Node sid_node = g.get_final_intent();
	DBGF("SID:          %s", sid_node.to_string().c_str());
	char *sid_from_key_hash = SID_from_keypair(pubkey);
	DBGF("Pub key hash: %s", sid_from_key_hash);
	if (strcmp(sid_node.to_string().c_str(), sid_from_key_hash) != 0) {
		WARN("Hash of received public key does not match SID! Closing connection.");
		return 0;
	}
	if (verify(pubkey, keys, keybufsize+tempkeybufsize+2*sizeof(uint32_t), sig, siglen) != 1) {
		WARN("Unable to verify signature on temporary RSA keypair! Closing connection.");
		return 0;
	}


	/* Generate pre-master secret and send to server, encrypted with sessionPubKey */
	unsigned char* pms = (unsigned char*)malloc(PRE_MASTER_SECRET_LENGTH);
    if (RAND_bytes(pms, PRE_MASTER_SECRET_LENGTH) != 1) {
        ERROR("ERROR: Couldn't generate pre-master secret");
		return 0;
    }
	if (VERBOSITY >= V_DEBUG) {
		DBG("Pre-Master Secret:");
		print_bytes(pms, PRE_MASTER_SECRET_LENGTH);
	}

	int ciphertext_len;
	if ( (ciphertext_len = pub_encrypt(sessionPubkey, 
							pms, PRE_MASTER_SECRET_LENGTH, 
							buf, XIA_MAXBUF)) == -1 ) {
		ERROR("ERROR: Unable to encrypt session key");
		return 0;
	}
    
	n = 0;
	offset = 0;
	while (offset < ciphertext_len) {
		if ((n = Xsend(xssl->sockfd, &buf[offset], ciphertext_len-offset, 0)) < 0) {
			ERROR("ERROR sending pre-master secret");
			return 0;
		}
		offset += n;
	}
	

	/* Init symmetric session ciphers with pre-master secret.
	   Client encrypt context initialized with same key data as
	   server decrypt context and vice versa. */
	uint32_t salt[] = SALT;
	if (aes_init(pms, PRE_MASTER_SECRET_LENGTH/2, 
				 &pms[PRE_MASTER_SECRET_LENGTH/2], PRE_MASTER_SECRET_LENGTH/2, 
				 (unsigned char *)&salt, xssl->en, xssl->de)) {
		ERROR("ERROR initializing AES ciphers");
		return 0;
	}
	free(pms);

	
	/* For now, omitting CLIENT DONE */


	return 1;
}
Пример #6
0
void process(int peer)
{
	fhConfig fhc;
	char *buf = NULL;
	uint32_t count = 0;
	int n;

	signal(SIGINT, handler);

	fd_set fds;
	FD_ZERO(&fds);
	FD_SET(peer, &fds);

	struct timeval tv;
	tv.tv_sec = 5;
	tv.tv_usec = 0;

	n = Xselect(peer + 1, &fds, NULL, NULL, &tv);
	if (n < 0) {
		printf("select failed\n");
		goto done;
	
	} else if (n == 0) {
		printf("recv timeout\n");
		goto done;
	
	} else if (!FD_ISSET(peer, &fds)) {
		// this shouldn't happen!
		printf("something is really wrong, exiting\n");
		goto done;
	}

	if (Xrecv(peer, &fhc, sizeof(fhc), 0) < 0) {
		printf("Unable to get configuration block\n");
		goto done;
	}

	fhc.numPkts = ntohl(fhc.numPkts);
	fhc.delay   = ntohl(fhc.delay);
	fhc.pktSize = ntohl(fhc.pktSize);
	// need to have at least enough room for the sequence #
	fhc.pktSize = MAX(fhc.pktSize, sizeof(unsigned));
	if (fhc.numPkts == 0)
		say("packet count = non-stop\n");
	else
		say("packet count = %d\n", fhc.numPkts);
	say("packet size = %d\n", fhc.pktSize);
	say("inter-packet delay = %d\n", fhc.delay);


	if (!(buf = (char *)malloc(fhc.pktSize))) {
		printf("Memory error\n");
		goto done;
	}
		
	while (!timetodie) {
		if (fhc.numPkts > 0 && count == fhc.numPkts)
			break;
		printf("sending packet %d\n", count);
		data(count, buf, sizeof(buf));
		Xsend(peer, buf, sizeof(buf), 0);
		count++;
		if (fhc.delay != 0)
			usleep(fhc.delay);
	}
done:
	say("done\n");
	if (buf) 
		free(buf);
	Xclose(peer);
}