Beispiel #1
0
Datei: main.c Projekt: Azii/Uni
int bitcoin_parallel(const unsigned int processcount) {
	printf("\n\nStarting bitcoin_parallel\n");
	// Start, end time
	unsigned long start,end;
	// Set start time
	start = current_time_millis();

	// TODO: Create a Blockheader object and fill it with the initial data using the getWork Method
	Blockheader * b_header = malloc(sizeof(Blockheader));
	getWork(b_header);
	// TODO: Split the calculation of the hashes into several segments based on the processcount
	int hashes_per_process = MAX_HASHES / processcount;
	for (int i = 0; i < processcount; i++)
	{
		Blockheader * temp = malloc(sizeof(Blockheader));
		memcpy(temp, b_header, sizeof(Blockheader));
		//temp->nonce += i * 0;
	}
	// TODO: Spawn a process for each segment
	// TODO: If a hash has the appropriate difficulty print it on the console using print_hash
	// TODO: Wait until all children finish before exiting

	end = current_time_millis();
	printf("Calculation finished after %.3fs\n", (double) (end - start) / 1000);

	return EXIT_FAILURE;
}
Beispiel #2
0
Datei: main.c Projekt: Azii/Uni
int bitcoin_parallel(const unsigned int processcount) {
	printf("\n\nStarting bitcoin_parallel\n");
	// Start, end time
	unsigned long start,end;
	// Set start time
	start = current_time_millis();

	// TODO: Create a Blockheader object and fill it with the initial data using the getWork Method
	Blockheader * blockheader = malloc(sizeof(Blockheader));
	getWork(blockheader);
	// TODO: Split the calculation of the hashes into several segments based on the processcount
	int segment_size = ceil((double) MAX_HASHES / processcount);
	unsigned long starting_nonce = toulong(blockheader->nonce);
	//printf("starting_nonce am anfang: %ld\n", starting_nonce);
	
	// TODO: Spawn a process for each segment
	int pos = 0;
	int * child_pids = malloc(sizeof(int) * processcount);
	for (int i = 0; i < processcount; i++)
	{
		child_pids[i] = 0;
	}
	
	for (; pos < processcount; pos++)
	{
		child_pids[pos] = fork();
		if (child_pids[pos] < 0)
		{
			printf("failed forking");
			return EXIT_FAILURE;
		}
		if (child_pids[pos] == 0)
		{
			break;
		}
	}
	
	if (pos < processcount)
	{
		starting_nonce += pos * segment_size;
		char * n = to_reversed_char_arr(starting_nonce);
		memcpy(&(blockheader->nonce), n, sizeof(char) * 4);
		calculate_hash(blockheader, segment_size);
		return EXIT_SUCCESS;
	}
	
	int status;
	for (int i = 0; i < processcount; i++)
	{
		wait(&status);
	}
	
	end = current_time_millis();
	printf("Calculation finished after %.3fs\n", (double) (end - start) / 1000);

	return EXIT_SUCCESS;
}
Beispiel #3
0
Datei: main.c Projekt: Azii/Uni
/*
Calculates Blockhashes in a simple loop.
*/
int bitcoin_simple() {
	printf("Starting bitcoin_simple\n");
	// Start, end time
	unsigned long start,end;
	// Set start time
	start = current_time_millis();


	// Creates and retrieves the Block-Header information
	Blockheader * blockheader = malloc(sizeof(Blockheader));
	// The getWork method fills an empty Blockheader struct with all the neccesary information needed to calcualte the Hash of a Block.
	getWork(blockheader);
	// The nonce is the value that is incremented in each run to get a different hash value
	char * n = malloc(sizeof(char)*4);
	memcpy(n,&(blockheader->nonce),sizeof(char)*4);
	// The values in the Blockheader are actually in reverse byte order and need to be reversed in order to increment the nonce value. 
	byte_reversal(n,sizeof(char)*4);
	// Convert the 4 byte long raw data into an unsinged long 
	unsigned long starting_nonce = n[0] << 24 | n[1] << 16 | n[2] << 8 | n[3];
	// The nonce value we received in the getWork method is the actual starting nonce value. We start to calculate hashes with this initial nonce and increase it by one in each run. 
	unsigned long nonce = starting_nonce;
	char * hash;
	// In practice it is very hard to find a valid hash, so in this exercise we will limit the amount of hashes we calculate.
	for(;nonce<=(starting_nonce+MAX_HASHES);nonce++) {
		// put current nonce in blockheader object
		// first, shift long back to char[4]
		n[0] = nonce >> 24;
		n[1] = nonce >> 16;
		n[2] = nonce >> 8;
		n[3] = nonce;
		// reverse byte order
		byte_reversal(n,sizeof(char)*4);
		// put n into blockheader
		blockheader->nonce[0] = n[0];
		blockheader->nonce[1] = n[1];
		blockheader->nonce[2] = n[2];
		blockheader->nonce[3] = n[3];
		// calculate the hash using the sha-256 hashing algorithm
		size_t size = getData(blockheader,&hash);
		size = sha256_digest(hash,size,&hash);
		// To calculate a valid hash, we need to do two hashing passes
		size = sha256_digest(hash,size,&hash);
		if(check_hash(hash,(int)size))
		{
			printf("%ld : ", nonce);
			print_hash(hash,size);
		}
	}

	end = current_time_millis();
	printf("Calculation finished after %.3fs\n", (double) (end - start) / 1000);

	free(blockheader);
	return EXIT_SUCCESS;

}
Beispiel #4
0
// This function is used to connect to the server. It takes the socket ID and the 
// server's port number as input parameters. The socket ID is used to find the TCB entry.  
// This function sets up the TCB's server port number and a SYN segment to send to
// the server using snp_sendseg(). After the SYN segment is sent, a timer is started. 
// If no SYNACK is received after SYNSEG_TIMEOUT timeout, then the SYN is 
// retransmitted. If SYNACK is received, return 1. Otherwise, if the number of SYNs 
// sent > SYN_MAX_RETRY,  transition to CLOSED state and return -1.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
int srt_client_connect(int sockfd, unsigned int server_port)
{
	printf("srt_client_connect\n");
	if(sockfd < 0 || sockfd > MAX_TRANSPORT_CONNECTIONS || clients[sockfd] == NULL)
	{
		printf("Error in srt_client_connect sockfd = %d max clients supported = %d\n", sockfd, MAX_TRANSPORT_CONNECTIONS);
		return -1;
	}
	client_tcb_t *client = clients[sockfd];
	seg_t segment;
	bzero(&segment,sizeof(segment));
	segment.header.src_port = client->client_portNum;
	segment.header.dest_port = client->svr_portNum = server_port;
	segment.header.type = SYN;
	segment.header.seq_num = 0;
	segment.header.length = 0;
	int trialNum = 0 ;
	//  first trial
	if(snp_sendseg(mainTcpSockId,&segment) < 0){ // error check for sendseg when there is TCP socket error
		printf("Error in sending message in TCP layer = %d \n", mainTcpSockId);
		return -1;
	}
	long start_time = current_time_millis(); // timer started
	trialNum++; // increment trial num
	client->state = SYNSENT ;
	while(client->state == SYNSENT){
		wait_for_some_time(LOOP_WAITING_TIME);
		long now = current_time_millis();
		long diff = now - start_time ;
		if((diff ) > SYN_TIMEOUT_MS){
			printf("TIMEOUT in connect %d for trial num = %d \n", sockfd, trialNum);
			if(trialNum < SYN_MAX_RETRY){
				printf("resending segment \n");
				if(snp_sendseg(mainTcpSockId,&segment) < 0){ // error check for sendseg when there is TCP socket error
					printf("ERROR in sending message sockfd = %d \n", sockfd);
					return -1;
				}
				start_time = (long)time(NULL); // reset timer
				trialNum++;
			}else{
				printf("MAX TRIAL reached in connect segment of sock fd %d\n" ,sockfd);
				client->state = CLOSED;
				return -1;
			}
		}	
	}
 	printf("srt_client_connect ends \n");
 	fflush(stdout);
  return 1; // returning success it can be rechecked with state = CONNECTED
}
Beispiel #5
0
int generate_mandelbrot_simple(const char* filename)
{
	int return_code = EXIT_FAILURE;
	unsigned long start, end;

	// Allocate buffer for picture data
	pixel_data_t *data = calloc(WIDTH * HEIGHT, sizeof(pixel_data_t));
	if (data)
	{
		// Create and open the output file
		FILE *file = fopen(filename, "wb");
		if (file)
		{
			// write the header
			write_bitmap_header(file, WIDTH, HEIGHT);

			// init time measurement
			start = current_time_millis();

			// calculate the data for the picture
			calc_mandelbrot(data, WIDTH, HEIGHT, 0, 0, WIDTH, HEIGHT);

			// write the data to the file
			fwrite(data, sizeof(pixel_data_t), WIDTH * HEIGHT, file);

			// close the file
			fclose(file);

			// print the measured time
			end = current_time_millis();
			printf("%.2f seconds\n", (double) (end - start) / 1000);

			// success
			return_code = EXIT_SUCCESS;
		}
		else
		{
			printf("Could not create the output file: %s\n", strerror(errno));
		}

		// free buffer
		free(data);
	}
	else
	{
		printf("Could not allocate memory for buffer.\n");
	}

	return return_code;
}
Beispiel #6
0
void send_unsent_segments(client_tcb_t *client){
	pthread_mutex_lock(client->bufMutex);
	printf("send_unsent_segments starts \n");
	while(client->sendBufunSent!=NULL && client->unAck_segNum < GBN_WINDOW){
		// 1. send the segment
		// 2. check if it was succesfull
		// 3. update the sent time 
		// 4. start the timeout thread if required which means client->unAck_segNum should be zero 
		// 5. switch to next segment
		if(snp_sendseg(mainTcpSockId,(seg_t*)client->sendBufunSent)){
			printf("DATA PACKET SENT sequence number %d sent to server \n",client->sendBufunSent->seg.header.seq_num);
			client->sendBufunSent->sentTime = current_time_millis();
			client->sendBufunSent = client->sendBufunSent->next;
			if(client->unAck_segNum == 0) { // check 
				printf("TIMEOUT thread create called\n");
				pthread_t timeout_thread;
				pthread_create(&timeout_thread,NULL,sendBuf_timer, (void*)client);
			}
			client->unAck_segNum++;
			printf("UNACKED count = %d \n", client->unAck_segNum);
		}else{
			printf("ERROR (send_unsent_segments) in snp_sendseg exiting TCP error \n");
			exit(-1);
		}
	}
	pthread_mutex_unlock(client->bufMutex);
	printf("send_unsent_segments ends \n");
	fflush(stdout);
}
Beispiel #7
0
Datei: main.c Projekt: Azii/Uni
int bitcoin_loop(const unsigned int processcount) {
	printf("\n\nStarting bitcoin_loop\n");
	// Start, end time
	unsigned long start,end;
	// Set start time
	start = current_time_millis();
	
	Blockheader * blockheader = malloc(sizeof(Blockheader));
	getWork(blockheader);
	// TODO: Split the calculation of the hashes into several segments based on the processcount
	int segment_size = ceil((double)MAX_HASHES / processcount);
	
	for (int i = 0; i < processcount; i++)
	{
		calculate_hash(blockheader, segment_size);
		//printf("nonce after run #%i: %ld\n", i, toulong(blockheader->nonce));
	}

	end = current_time_millis();
	printf("Calculation finished after %.3fs\n", (double) (end - start) / 1000);
	free(blockheader);
	return EXIT_SUCCESS;
}
Beispiel #8
0
void handle_timeout_resend(client_tcb_t *client){
	printf("handle_timeout_resend starts\n");
	int unack_count = 0 ;
	segBuf_t *head = client->sendBufHead;
	pthread_mutex_lock(client->bufMutex);
	while(head && unack_count < client->unAck_segNum){
		if(snp_sendseg(mainTcpSockId,(seg_t*)head)){
			printf("DATA PACKET RESENT sequence number %d sent to server total UNACKED =  %d \n",head->seg.header.seq_num, client->unAck_segNum );
			head->sentTime = current_time_millis();
			head = head->next;
			unack_count++;
		}else{
			printf("ERROR (handle_timeout_resend) in snp_sendseg exiting TCP error \n");
			exit(-1);
		}
	}
	pthread_mutex_unlock(client->bufMutex);
	printf("handle_timeout_resend ends\n");
}
Beispiel #9
0
// This thread continuously polls send buffer to trigger timeout events
// It should always be running when the send buffer is not empty
// If the current time -  first sent-but-unAcked segment's sent time > DATA_TIMEOUT, a timeout event occurs
// When timeout, resend all sent-but-unAcked segments
// When the send buffer is empty, this thread terminates
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void* sendBuf_timer(void *clienttcb)
{	
  client_tcb_t *client = (client_tcb_t *) clienttcb ;
  printf("TIMEOUT thread started\n");	
  while(1){
  		printf("sendBuf_timer sleeping ... \n");
  		wait_for_some_time(SENDBUF_POLLING_INTERVAL);
  		printf("POLLING sendBuf_timer\n");
  		if(client->unAck_segNum == 0 || client->state != CONNECTED) {
  			printf("NOTHING to send in timeout buffer hence exiting buffer thread\n");
			pthread_exit(NULL);
		}else{
  			long currentTime = current_time_millis();
  			long diff = currentTime - client->sendBufHead->sentTime;
  			if(diff >= DATA_TIMEOUT){
  				printf("TIMEOUT for sent-but-unAcked\n");
  				//resend all in buffer
  				handle_timeout_resend(client);
  			}
  		}
  }
  return 0;
}
Beispiel #10
0
Datei: main.c Projekt: Azii/Uni
int bitcoin_loop(const unsigned int processcount) {
	printf("\n\nStarting bitcoin_loop\n");
	// Start, end time
	unsigned long start,end;
	// Set start time
	start = current_time_millis();

	// TODO: Create a Blockheader object and fill it with the initial data using the getWork Method
	Blockheader * b_header = malloc(sizeof(Blockheader));
	getWork(b_header);
	// TODO: Split the calculation of the hashes into several segments based on the processcount
	int * pids = malloc(sizeof(int) * processcount);
	for (int i = 0; i < processcount; i++)
	{
		if (i > 0)
		{
			if (pids[i - 1] == 0)
			{
				break;
			}
		}
		pids[i] = fork();
	}
	if (pids[processcount - 1] != 0)
	{
		
	}
	
	
	int child_pid = 0;
	int num_process = 0;
	
	for (int i = 0; i < processcount - 1; i++)
	{	
		child_pid = fork();
		
		if (child_pid != 0)
			break;
		
		num_process++;
	}
	printf("%i", num_process);
	
	calc_hashes((int)floor(MAX_HASHES / processcount));
	wait(child_pid);
	
	return 0;
	
	/*char * n = malloc(sizeof(char) * 4);
	memcpy(n, &(b_header->nonce), sizeof(char) * 4);
	byte_reversal(n, sizeof(char) * 4);
	
	// copy paste
	unsigned long starting_nonce = n[0] << 24 | n[1] << 16 | n[2] << 8 | n[3];
	starting_nonce += 0;
	// The nonce value we received in the getWork method is the actual starting nonce value. We start to calculate hashes with this initial nonce and increase it by one in each run. 
	unsigned long nonce = starting_nonce;
	char * hash;
	// In practice it is very hard to find a valid hash, so in this exercise we will limit the amount of hashes we calculate.
	for( ; nonce<=(starting_nonce + MAX_HASHES); nonce++) {
		// put current nonce in blockheader object
		// first, shift long back to char[4]
		n[0] = nonce >> 24;
		n[1] = nonce >> 16;
		n[2] = nonce >> 8;
		n[3] = nonce;
		// reverse byte order
		byte_reversal(n,sizeof(char)*4);
		// put n into blockheader
		blockheader->nonce[0] = n[0];
		blockheader->nonce[1] = n[1];
		blockheader->nonce[2] = n[2];
		blockheader->nonce[3] = n[3];
		// calculate the hash using the sha-256 hashing algorithm
		size_t size = getData(blockheader,&hash);
		size = sha256_digest(hash,size,&hash);
		// To calculate a valid hash, we need to do two hashing passes
		size = sha256_digest(hash,size,&hash);
		if(check_hash(hash,(int)size))
		{
			printf("%ld : ", nonce);
			print_hash(hash,size);
		}
	}
	
	
	if(child_pid != 0)
		wait(child_pid);
	
	
	
	// TODO: If a hash has the appropriate difficulty (hint: check_hash) print it on the console using print_hash

	end = current_time_millis();
	printf("Calculation finished after %.3fs\n", (double) (end - start) / 1000);

	return EXIT_FAILURE;*/
}
Beispiel #11
0
int generate_mandelbrot_loop(const char* filename)
{
	int return_code = EXIT_FAILURE;
	unsigned long start, end;
	
	// Create and open the output file, write header
	FILE *file = fopen(filename, "wb");
	if (!file) {
		printf("Could not create the output file: %s\n", strerror(errno));
		return return_code;
	}
	
	// write header
	write_bitmap_header(file, WIDTH, HEIGHT);
	
	// close file handler
	fclose(file);
	
	// init time measurement
	start = current_time_millis();
	//return -1;
	// Loop
	int i;

	for (i=1; i<=MAX_PROCESSES; i++) {
		
		// Slicing: Slice width, height and offsets
		int sliceWidth   = WIDTH;
		int sliceHeight  = HEIGHT/MAX_PROCESSES;
		int widthOffset  = 0;
		int heightOffset = (i-1) * sliceHeight;
		
		// Allocate buffers for picture data
		pixel_data_t *data = calloc(sliceWidth * sliceHeight, sizeof(pixel_data_t));
		if (data)
		{
			// Open the output file
			FILE *file = fopen(filename, "a+");
			if (file)
			{
				// calculate the data for the picture
				calc_mandelbrot(data, WIDTH, HEIGHT, widthOffset, heightOffset, sliceWidth, sliceHeight);
				// write the data to the file
				fwrite(data, sizeof(pixel_data_t), sliceWidth * sliceHeight, file);

				// close the file
				fclose(file);
			}
			else
			{
				printf("Could not open the output file: %s\n", strerror(errno));
				return return_code;
			}

			// free buffer
			free(data);
		}
		else
		{
			printf("Could not allocate memory for buffer.\n");
			return return_code;
		}
	
	}

	// print the measured time
	end = current_time_millis();
	printf("\n%.2f seconds\n", (double) (end - start) / 1000);
	
	// success
	return_code = EXIT_SUCCESS;

	return return_code;
}
Beispiel #12
0
int generate_mandelbrot_parallel(const char* filename)
{
	int return_code = EXIT_FAILURE;
	unsigned long start, end;
	
	// Create and open the output file, write header
	FILE *file = fopen(filename, "wb+");
	if (!file) {
		printf("Could not create the output file: %s\n", strerror(errno));
		return return_code;
	}
	
	// write header
	write_bitmap_header(file, WIDTH, HEIGHT);
	
	// store header size for later offset
	long headerOffset = ftell(file);
	
	// close file handler
	fclose(file);

	// init time measurement
	start = current_time_millis();

	// set up loop and forking variables
	int i, status;
	pid_t pid = 1, wpid;

	for (i=0; i<=MAX_PROCESSES; i++) {
		if (pid>0) { // in parent process -> fork
			pid = fork();
		}
		if (pid<0) { // error while forking -> exit program
			printf("Error while forking: %s\n", strerror(errno));
			return return_code;
		} else if (pid==0) { // in child process -> do image generation work
			
			// Slicing: Slice the dimensions of the image into equally sized, horizontal stripes
			int sliceWidth   = WIDTH;
			int sliceHeight  = HEIGHT/MAX_PROCESSES;
			int widthOffset  = 0;
			int heightOffset = (i-1) * sliceHeight;
		
			// Allocate buffers for picture data
			pixel_data_t *data = calloc(sliceWidth * sliceHeight, sizeof(pixel_data_t));
			if (data)
			{
				// Open the output file
				FILE *file = fopen(filename, "rb+");
				if (file)
				{
					// calculate the data for the picture
					calc_mandelbrot(data, WIDTH, HEIGHT, widthOffset, heightOffset, sliceWidth, sliceHeight);

					// seek right position
					// SizeOfPixel * NumberOfPixels * PositionOfTheCurrentSlice + HeaderSize
					long byteoffset = sizeof(pixel_data_t)*sliceWidth*sliceHeight*(i-1) + headerOffset;
					fseek(file, byteoffset, SEEK_SET);
				
					// write the data to the file
					fwrite(data, sizeof(pixel_data_t), sliceWidth * sliceHeight, file);

					// close the file
					fclose(file);
					
					// exit the process, return to main
					exit(1);
				}
				else
				{
					printf("Could not open the output file: %s\n", strerror(errno));
					return return_code;
				}

				// free buffer
				free(data);
			}
			else
			{
				printf("Could not allocate memory for buffer.\n");
				return return_code;
			}
		}
	
	}

	// wait for children to finish
	for (i=0; i<MAX_PROCESSES; i++) {
		wait(&status);
	}
	
	//re-write header in case it got overwritten - yes we know this is a bug. we don't know how to solve it. this gets around the symptoms, it's as good as we got it
	file = fopen(filename, "rb+");
	if (!file) {
		printf("Could not create the output file: %s\n", strerror(errno));
		return return_code;
	}
	fseek(file, 0, SEEK_SET);
	// write header
	write_bitmap_header(file, WIDTH, HEIGHT);
	
	// close file handler
	fclose(file);

	// print the measured time
	end = current_time_millis();
	printf("\n%.2f seconds\n", (double) (end - start) / 1000);
	
	// success
	return_code = EXIT_SUCCESS;

	return return_code;
}