// File: luigix25[P]SSLP/server_files/server.cpp
// Function: main
int main(int argc,char **argv){


	if(argc != 2){
		cout<<"[Error] missing port!"<<endl;
		exit(-1);
	}

	signal(SIGPIPE, SIG_IGN);					//ignoro sigpipe
	signal (SIGINT,close_handler);				//gestisco i ctrl-c

	struct sockaddr_in clientAddress;

	int port = atoi(argv[1]);
	int fdmax;
	unsigned int addrlen;
	int i,status,new_sock;
	int cmd;
	fd_set read_fds;
		
	if(port <= 0 || port >= USHRT_MAX){
		cout<<"[Error] Invalid Port"<<endl;
		exit(-1);
	}


	memset(&clientAddress,0,sizeof(clientAddress));

	server_socket = initialize_server(port);

	cout<<"[LOG] Waiting connections on port "<<port<<endl;

	
	FD_ZERO(&master);	
	FD_ZERO(&read_fds);
	FD_SET(server_socket,&master);
	fdmax = server_socket;

	client_socket = NetSocket();

	bool alreadyConnected = false;


	while(true){
		read_fds = master;
		if(select(fdmax+1,&read_fds,NULL,NULL,NULL) <=0){
			perror("[Error] Select");
			exit(-1);
		}

		for(i = 0; i <= fdmax; i++){
			if(FD_ISSET(i,&read_fds)){	
				if(i == server_socket){ 						//new connection
					memset(&clientAddress,0,sizeof(clientAddress));
					addrlen = sizeof(clientAddress);
					new_sock = accept(server_socket,(struct sockaddr*)&clientAddress,&addrlen);
					
					if(new_sock < 0){
						perror("[Error] accept\n");
						continue;
					}

					if(alreadyConnected){					
						close(new_sock);						//refuse new connections
						continue;
					}

					FD_SET(new_sock,&master);
					if(new_sock > fdmax) 
						fdmax = new_sock;
					
					client_socket.setSocket(new_sock);
					alreadyConnected = true;

					if(!initial_protocol(client_socket)){
						client_socket.closeConnection();
						KeyManager::destroyKeys();
						alreadyConnected = false;
						FD_CLR(new_sock,&master);
					}

					continue;


				} else {

					status = receive_command(cmd);
					if(!status){
						cout<<"[LOG] Client Disconnected"<<endl;
						client_socket.closeConnection();
						KeyManager::destroyKeys();
						alreadyConnected = false;
						FD_CLR(i,&master);							//remove socket from select

					} else {
						if(!select_command(cmd)){
							client_socket.closeConnection();
							KeyManager::destroyKeys();
							alreadyConnected = false;
							FD_CLR(i,&master);
						}
					}

				}
			}

		}	

	}
	
	//close(server_socket);											//no more clients allowed

	return 0;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x808b
movq 0xbf62(%rip), %rdi      # 0x13fc8
leaq 0x71ae(%rip), %rsi      # 0xf21b
callq 0x5500
movq %rax, %rdi
movq 0xbf3c(%rip), %rsi      # 0x13fb8
callq 0x5550
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x5690
movl $0xd, %edi
movl $0x1, %esi
callq 0x5670
movl $0x2, %edi
leaq -0x1fb6(%rip), %rsi     # 0x60f0
callq 0x5670
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x5890
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jle 0x80ca
cmpl $0xffff, -0x24(%rbp)    # imm = 0xFFFF
jl 0x80f6
movq 0xbef7(%rip), %rdi      # 0x13fc8
leaq 0x7159(%rip), %rsi      # 0xf231
callq 0x5500
movq %rax, %rdi
movq 0xbed1(%rip), %rsi      # 0x13fb8
callq 0x5550
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x5690
leaq -0x20(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x52e0
movl -0x24(%rbp), %edi
callq 0x6d50
movl %eax, 0xc544(%rip)      # 0x14658
movq 0xbead(%rip), %rdi      # 0x13fc8
leaq 0x7124(%rip), %rsi      # 0xf246
callq 0x5500
movq %rax, %rdi
movl -0x24(%rbp), %esi
callq 0x5950
movq %rax, %rdi
movq 0xbe7c(%rip), %rsi      # 0x13fb8
callq 0x5550
leaq 0xc488(%rip), %rax      # 0x145d0
movq %rax, -0xd0(%rbp)
movl $0x0, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
cmpq $0x10, %rax
jae 0x818b
movq -0xd0(%rbp), %rax
movl -0xc4(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0x8159
jmp 0x818d
jmp 0x818f
leaq -0xc0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movl $0x0, -0xd4(%rbp)
movl -0xd4(%rbp), %eax
cmpq $0x10, %rax
jae 0x81d9
movq -0xe0(%rbp), %rax
movl -0xd4(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd4(%rbp)
jmp 0x81a7
jmp 0x81db
movl 0xc477(%rip), %eax      # 0x14658
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, -0xf8(%rbp)
movl 0xc456(%rip), %eax      # 0x14658
movl $0x40, %ecx
cltd
idivl %ecx
movq -0xf8(%rbp), %rdx
movslq %eax, %rcx
leaq 0xc3b5(%rip), %rax      # 0x145d0
orq (%rax,%rcx,8), %rdx
leaq 0xc3aa(%rip), %rax      # 0x145d0
movq %rdx, (%rax,%rcx,8)
movl 0xc428(%rip), %eax      # 0x14658
movl %eax, -0x28(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x9180
movl -0xe8(%rbp), %eax
movl %eax, 0xc405(%rip)      # 0x14650
movb -0xe4(%rbp), %al
movb %al, 0xc3fd(%rip)       # 0x14654
movb $0x0, -0xe9(%rbp)
leaq -0xc0(%rbp), %rdi
leaq 0xc364(%rip), %rsi      # 0x145d0
movl $0x80, %edx
callq 0x5480
movl -0x28(%rbp), %edi
addl $0x1, %edi
leaq -0xc0(%rbp), %rsi
xorl %eax, %eax
movl %eax, %r8d
movq %r8, %rdx
movq %r8, %rcx
callq 0x54f0
cmpl $0x0, %eax
jg 0x82ae
leaq 0x6fca(%rip), %rdi      # 0xf269
callq 0x5490
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x5690
movl $0x0, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x28(%rbp), %eax
jg 0x8584
movl -0x30(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq -0xc0(%rbp,%rax,8), %rax
movq %rax, -0x100(%rbp)
movl -0x30(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x100(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x8574
movl -0x30(%rbp), %eax
cmpl 0xc346(%rip), %eax      # 0x14658
jne 0x8459
leaq -0x20(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x52e0
movl $0x10, -0x2c(%rbp)
movl 0xc323(%rip), %edi      # 0x14658
leaq -0x20(%rbp), %rsi
leaq -0x2c(%rbp), %rdx
callq 0x51c0
movl %eax, -0x38(%rbp)
cmpl $0x0, -0x38(%rbp)
jge 0x835c
leaq 0x6f26(%rip), %rdi      # 0xf278
callq 0x5490
jmp 0x8576
testb $0x1, -0xe9(%rbp)
je 0x8372
movl -0x38(%rbp), %edi
callq 0x5aa0
jmp 0x8576
movl -0x38(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, -0x108(%rbp)
movl -0x38(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x108(%rbp), %rdx
movslq %eax, %rcx
leaq 0xc224(%rip), %rax      # 0x145d0
orq (%rax,%rcx,8), %rdx
leaq 0xc219(%rip), %rax      # 0x145d0
movq %rdx, (%rax,%rcx,8)
movl -0x38(%rbp), %eax
cmpl -0x28(%rbp), %eax
jle 0x83c9
movl -0x38(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x38(%rbp), %esi
leaq 0xc27d(%rip), %rdi      # 0x14650
callq 0x91a0
movb $0x1, -0xe9(%rbp)
leaq 0xc26a(%rip), %rdi      # 0x14650
callq 0x6fd0
testb $0x1, %al
jne 0x8454
leaq 0xc25a(%rip), %rdi      # 0x14650
callq 0x91c0
callq 0xe750
movb $0x0, -0xe9(%rbp)
movl -0x38(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
xorq $-0x1, %rax
movq %rax, -0x110(%rbp)
movl -0x38(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x110(%rbp), %rdx
movslq %eax, %rcx
leaq 0xc18b(%rip), %rax      # 0x145d0
andq (%rax,%rcx,8), %rdx
leaq 0xc180(%rip), %rax      # 0x145d0
movq %rdx, (%rax,%rcx,8)
jmp 0x8576
leaq -0x3c(%rbp), %rdi
callq 0x6e80
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jne 0x84fd
movq 0xbb4d(%rip), %rdi      # 0x13fc8
leaq 0x6e06(%rip), %rsi      # 0xf288
callq 0x5500
movq %rax, %rdi
movq 0xbb27(%rip), %rsi      # 0x13fb8
callq 0x5550
leaq 0xc1b3(%rip), %rdi      # 0x14650
callq 0x91c0
callq 0xe750
movb $0x0, -0xe9(%rbp)
movl -0x30(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
xorq $-0x1, %rax
movq %rax, -0x118(%rbp)
movl -0x30(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x118(%rbp), %rdx
movslq %eax, %rcx
leaq 0xc0e4(%rip), %rax      # 0x145d0
andq (%rax,%rcx,8), %rdx
leaq 0xc0d9(%rip), %rax      # 0x145d0
movq %rdx, (%rax,%rcx,8)
jmp 0x8570
movl -0x3c(%rbp), %edi
callq 0x6cf0
testb $0x1, %al
jne 0x856e
leaq 0xc140(%rip), %rdi      # 0x14650
callq 0x91c0
callq 0xe750
movb $0x0, -0xe9(%rbp)
movl -0x30(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
xorq $-0x1, %rax
movq %rax, -0x120(%rbp)
movl -0x30(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x120(%rbp), %rdx
movslq %eax, %rcx
leaq 0xc071(%rip), %rax      # 0x145d0
andq (%rax,%rcx,8), %rdx
leaq 0xc066(%rip), %rax      # 0x145d0
movq %rdx, (%rax,%rcx,8)
jmp 0x8570
jmp 0x8572
jmp 0x8574
jmp 0x8576
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x82b5
jmp 0x825e
nopl (%rax)