Example #1
0
int main(int argc, char** argv) {
    int socket;

    int rc;
    uint16_t msg_size = MAX_MSGSIZE;

    char buffer[MAX_MSGSIZE + 1];
    char msg[MAX_MSGSIZE + 1];

#ifdef _WIN32
    WSADATA wsaData;
    rc = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (rc != 0) {
        printf("WSAStartup failed with error: %d\n", rc);
        goto err;
    }	
#endif

    ProcessArgs(argc, argv);
    memset(buffer, 0, MAX_MSGSIZE + 1);
    memset(msg, 0, MAX_MSGSIZE + 1);

    strcpy(msg, "Hello, this is the client!");

    if (bIsServer) {
        socket = announce(OPTRC_FILE);
        if (socket == INVALID_SOCKET) {
            rc = -1;
            goto err;
        }

        rc = recvdata(socket, buffer, &msg_size);
        if (rc == SOCKET_ERROR) {
            goto err;
        }

        printf("%s\n", buffer);
    } else {
        socket = locate(OPTRC_FILE);
        if (socket == INVALID_SOCKET) {
            rc = -1;
            goto err;
        }

        rc = senddata(socket, msg, strlen(msg));
        if (rc == SOCKET_ERROR) {
            goto err;
        }
    }

err:
#ifdef _WIN32
	closesocket(socket);
	WSACleanup();
#else
    close(socket);
#endif
    return rc;
}
int main(int argc, char *argv[])
{
	
	// default to localhost
	char *server_name= "localhost";
	unsigned short port = DEFAULT_PORT;
	int i, loopcount, maxloop=-1;
	int retval;
	unsigned int addr;
	int socket_type = DEFAULT_PROTO;
	struct sockaddr_in server;

	if (argc < 3) {
		Usage();
	}
	
	if ((retval = WSAStartup(0x202, &wsaData)) != 0)
	{
	   fprintf(stderr,"WSAStartup() failed with error %d\n", retval);
		WSACleanup();
		return -1;
	}
	
	//	Get portnum
	port = atoi(argv[2]);
	
	memset(&server, 0, sizeof(server));
	server.sin_addr.s_addr = inet_addr(argv[1]);
	server.sin_family = AF_INET;
	server.sin_port = htons(port);
 
	conn_socket = socket(AF_INET, socket_type, 0); /* Open a socket */
	if (conn_socket <0 )
	{
		fprintf(stderr,"Client: Error Opening socket: Error %d\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}
	
	if (connect(conn_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
	{
		fprintf(stderr,"Client: connect() failed: %d\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}
 
	// Send the data
	senddata();

	// recieve a msg
	recvdata();
	
	closesocket(conn_socket);
	WSACleanup();
 
return 0;
}
Example #3
0
//~~~~~~~~~~~~~~~~~~~~~用户登陆~~~~~~~~~~~~~~~~~~~~~~~~~~~
//传送格式username*userpasswd#
int login(char username[20],char userpasswd[10])
{

top:	printf("ID: ");
	scanf("%s",username);
	strcpy(tempuname,username);
	printf("PASSWD: ");
	scanf("%s",userpasswd);
	strcat(username,"*");
	strcat(username,userpasswd);
	strcat(username,"#");
//	printf("%s\n",username);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
	struct FilePackage data;
	data=pack('L', username, " ",  0, 9,strlen(username),tempuname);
//	printf("%s\n",username);
	if(senddata(data)==0)
		exit(0);
//	printf("%s\n",username);
	if(recvdata(&data)==0)
		exit(0);
//	printf("%s\n",username);
//	printf("%s\n",data.buf);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	if(data.cmd == 'L' && data.ack == 0)
		{
			printf("\n\033[33mUsername or Password error!\033[0m\n\n");
			goto top;
		}
	if(data.cmd == 'L' && data.ack == 1)
		{
			printf("Login Success\n");
			printf("%s\n",data.buf);
			
//			SSL_shutdown(ssl);
// 			SSL_free(ssl);
// 			close(sockclient);
// 			SSL_CTX_free(ctx);
			return 1;
		}
	if(data.cmd == 'L' && data.ack == 2)
		{
			printf("\n\033[32mMaxnum connection!\033[0m\n\n");
			exit(0);
		}
	return 0;
}
Example #4
0
void mesgWnd(int sockfd)
{
  WINDOW *wnd, *pad;
  int max_y, max_x, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol;

  initscr();
  noecho();
  nocbreak();
  start_color();
  use_default_colors();
  init_pair(1, COLOR_WHITE, COLOR_BLUE);
  init_pair(2, COLOR_BLACK, COLOR_WHITE);
  getmaxyx(stdscr, max_y, max_x);

  wnd = newwin(0, 0, max_y, max_x - WNDWIDTH);
  pad = newpad(max_y, WNDWIDTH);

  wbkgd(wnd, COLOR_PAIR(1));
  wbkgd(pad, COLOR_PAIR(2));

  pminrow = pmincol = 0;
  sminrow = 0;
  smincol = max_x;
  smaxrow = max_y;
  smaxcol = max_x + WNDWIDTH;

  wprintw(wnd, "mainwindow> ");
  wrefresh(wnd);
  prefresh(pad, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol);

  for(;;)
    {
      char buf[BUFSIZ], *p;
      recvdata(sockfd, buf, BUFSIZ);
      if(strcmp(buf, "exit") == 0) break;
      wprintw(pad, "%s\n", buf);
      wrefresh(wnd);
      prefresh(pad, pminrow, pmincol, sminrow, smincol - WNDWIDTH - 1, smaxrow, smaxcol - WNDWIDTH - 1);
      sleep(3);
      prefresh(pad, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol);
    }
  endwin();
  delwin(wnd);
  delwin(pad);
}
Example #5
0
/* Fetch data, check if it's data for us and whether it's useable or not. If not, return
 * a failure code so we can delete this server from our list and continue with another one.
 */
int
recvpkt (
	SOCKET rsock,
	struct pkt *rpkt,    /* received packet (response) */
	unsigned int rsize,  /* size of rpkt buffer */
	struct pkt *spkt     /* sent     packet (request) */
	)
{
	int rdy_socks;
	int pkt_len;
	sockaddr_u sender;
	struct timeval timeout_tv;
	fd_set recv_fd;

	FD_ZERO(&recv_fd);
	FD_SET(rsock, &recv_fd);
	if (ENABLED_OPT(TIMEOUT)) 
		timeout_tv.tv_sec = (int) atol(OPT_ARG(TIMEOUT));
	else 
		timeout_tv.tv_sec = 68; /* ntpd broadcasts every 64s */
	timeout_tv.tv_usec = 0;
	rdy_socks = select(rsock + 1, &recv_fd, 0, 0, &timeout_tv);
	switch (rdy_socks) {
	case -1: 
		if (ENABLED_OPT(NORMALVERBOSE)) 
			perror("sntp recvpkt: select()");
		return PACKET_UNUSEABLE;
		break;
	case 0:
		if (ENABLED_OPT(NORMALVERBOSE))
			printf("sntp recvpkt: select() reached timeout (%u sec), aborting.\n", 
			       (unsigned)timeout_tv.tv_sec);
		return PACKET_UNUSEABLE;
		break;
	default:
		break;
	}
	pkt_len = recvdata(rsock, &sender, (char *)rpkt, rsize);
	if (pkt_len > 0)
		pkt_len = process_pkt(rpkt, &sender, pkt_len, MODE_SERVER, spkt, "recvpkt");

	return pkt_len;
}
Example #6
0
//~~~~~~~~~~~~~~~~~~~~~~~显示客户端目录~~~~~~~~~~~~~~~~~~~
void Show(char temp[100])
{
	char command [2];
	if((strncpy(command,temp,1),*command)=='1'||(strncpy(command,temp,1),*command)=='2'||(strncpy(command,temp,1),*command)=='3')
		return;
	if(strncmp(temp,"cd",2)==0)
		{
			char dir[40]={'\0'};
			temp[strlen(temp)-1]='\0';
			strncpy(dir,(&(*temp)+3),strlen(&(*temp)+3));
		
			/*
			printf("%d%s",strlen((&(*temp)+3)),(&(*temp)+3));
			printf("%d%s",strlen(dir),dir);
			if(dir[strlen(dir)]=='\0')
				printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
			*/
			
			chdir(dir);
			strcpy(temp,"ls");
		}
	system("clear");
	printf("\n\033[34m-----------------------------   \033[31mClient Files List   \033[34m----------------------------\033[0m\n");
	system(temp);
//	printf("\033[34m*******************************************************************************\033[0m\n");
	
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~显示服务器目录~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	
	senddata(pack('S', " ", " ",  0, 9,1,tempuname));
	struct FilePackage data;
	if(recvdata(&data)==0)
		exit(0);
	if(data.cmd=='S')
		{
			printf("\033[34m-----------------------------   \033[31mServer Files List   \033[34m----------------------------\033[0m\n");
			printf("%s\n",data.buf);
			printf("\033[34m--------------------------------------------------------------------------------\033[0m\n");
		}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
Example #7
0
/*************************************TcpClient::clientInit*********************************************/
void TcpClient::clientInit(sockaddr_in addr, int pipereadId) {
	pthread_mutex_init(&(this->mutex), NULL); //初始化互斥锁
	this->setstatus(false); //初始后状态字
	this->pipewrite = pipereadId; //设置写管道ID
	debug("Child:pipewriteID:%d child's process pid:%d\n" ,this->pipewrite,getpid());

	this->clientsock = socket(AF_INET, SOCK_STREAM, 0);
	if (this->clientsock == -1) {
		cout << "create client error" << endl;
	}

	if (0 == clientConnect(addr, sizeof(sockaddr_in), CONNECTTIMEOUT)) {
		//正常连接,则创建发送线程
		pthread_create(&(this->tid), NULL, PerTransFun, (void *) this); //创建周期性发数据的线程
	} else {
		//处理硬错误,错误代码111,此时connect不会阻塞到SIGALRM信号的发生
		cout << "Client(" << getpid() << "):connect timeout within given time";
		perror("");
		exit(-1);
	}
	//创建select来接收到来的包,并调用函数进行分析
	fd_set rset;
	FD_ZERO(&rset);
	struct timeval tt;
	tt.tv_sec = 1;
	tt.tv_usec = 0;

	while (1) {
		FD_SET(this->clientsock, &rset);
		select((this->clientsock) + 1, &rset, NULL, NULL, &tt);
		if (this->getstatus() && FD_ISSET(this->clientsock,&rset)) {
			this->coordinate.push_back(recvdata());
		} else if (!this->getstatus()) {
			break;
		}
	}
	pthread_join(this->tid, NULL);
	debug("Child:init end child's process pid:%d\n" , getpid());
}
Example #8
0
//
// Function: ClientThread
//
// Description:
//    This is a client thread that is spawned with each client
//    connection.  The thread simply reads data and writes it
//    back to the client until the socket is closed.
//
DWORD WINAPI ClientThread(LPVOID lpParam)
{
    SOCKET        s = (SOCKET)lpParam;
    int           ret,
                  len;
    char          szRecvBuff[MAX_BUFFER];

    while (1)
    {
        // Read data from client
        //
        len = MAX_BUFFER;
        if ((ret = recvdata(s, szRecvBuff, &len)) != 0)
        {
            printf("recv() failed: %d\n", ret);
            break;
        }
        if (len == 0)        // Graceful close
            break;
        szRecvBuff[len] = 0;
        printf("Read: %d bytes\n", len);
        // 
        // Write data back until socket closure, len will
        //  equal 0 when the socket has been gracefully closed
        // 
        if ((ret = senddata(s, szRecvBuff, &len)) != 0)
        {
            printf("send() failed: %d\n", ret);
            break;
        }
        if (len == 0)        // Graceful close
            break;
        printf("Wrote: %d bytes\n", len);
    }
    closesocket(s);
    return 0;
}
Example #9
0
/*
** Socket readable/timeout Callback:
** Read in the packet
** Unicast:
** - close socket
** - decrement n_pending_ntp
** - If packet is good, set the time and "exit"
** Broadcast:
** - If packet is good, set the time and "exit"
*/
void
sock_cb(
	evutil_socket_t fd,
	short what,
	void *ptr
	)
{
	sockaddr_u	sender;
	sockaddr_u *	psau;
	sent_pkt **	p_pktlist;
	sent_pkt *	spkt;
	int		rpktl;
	int		rc;

	INSIST(sock4 == fd || sock6 == fd);

	TRACE(3, ("sock_cb: event on sock%s:%s%s%s%s\n",
		  (fd == sock6)
		      ? "6"
		      : "4",
		  (what & EV_TIMEOUT) ? " timeout" : "",
		  (what & EV_READ)    ? " read" : "",
		  (what & EV_WRITE)   ? " write" : "",
		  (what & EV_SIGNAL)  ? " signal" : ""));

	if (!(EV_READ & what)) {
		if (EV_TIMEOUT & what)
			timeout_queries();

		return;
	}

	/* Read in the packet */
	rpktl = recvdata(fd, &sender, &rbuf, sizeof(rbuf));
	if (rpktl < 0) {
		msyslog(LOG_DEBUG, "recvfrom error %m");
		return;
	}

	if (sock6 == fd)
		p_pktlist = &v6_pkts_list;
	else
		p_pktlist = &v4_pkts_list;

	for (spkt = *p_pktlist; spkt != NULL; spkt = spkt->link) {
		psau = &spkt->addr;
		if (SOCK_EQ(&sender, psau))
			break;
	}
	if (NULL == spkt) {
		msyslog(LOG_WARNING,
			"Packet from unexpected source %s dropped",
			sptoa(&sender));
		return;
	}

	TRACE(1, ("sock_cb: %s %s\n", spkt->dctx->name,
		  sptoa(&sender)));

	rpktl = process_pkt(&r_pkt, &sender, rpktl, MODE_SERVER,
			    &spkt->x_pkt, "sock_cb");

	TRACE(2, ("sock_cb: process_pkt returned %d\n", rpktl));

	/* If this is a Unicast packet, one down ... */
	if (!spkt->done && (CTX_UCST & spkt->dctx->flags)) {
		dec_pending_ntp(spkt->dctx->name, &spkt->addr);
		spkt->done = TRUE;
	}


	/* If the packet is good, set the time and we're all done */
	rc = handle_pkt(rpktl, &r_pkt, &spkt->addr, spkt->dctx->name);
	if (0 != rc)
		TRACE(1, ("sock_cb: handle_pkt() returned %d\n", rc));
	check_exit_conditions();
}
Example #10
0
void *dataio (void *arg)
{
    struct msg_queue wpenq;		/* Pendientes de escritura */
    struct msg_queue rpenq;		/* Pendientes de lectura   */
    struct msg_queue to_krn;
    struct msg_queue tmp;
    struct mb_queue  no_sent;
    struct itc_event_info ieinfo;
    struct msg	     *mptr;
    ssize_t io_ret;
    int max, ret;
    fd_set wset, rset;
    char   *where;

    arg = NULL;

    itc_block_signal();

    init_msg_queue(&wpenq);
    init_msg_queue(&rpenq);

    while (1)
    {
	FD_ZERO(&wset);
	FD_ZERO(&rset);
	/*
         * Add itc file descriptor
         */
	FD_SET(itc_event, &rset);
	max = itc_event;

	/*
	 * Add all sockets scaning read events 
	 */
	
	ret = fill_fdset(&rpenq, &rset);
	max = ( max > ret ) ? max : ret;
	/*
         * Add all sockets scaning write envents
         */
	ret = fill_fdset(&wpenq, &wset);
	max = ( max > ret ) ? max : ret;
	
	ret = select_nosignal(max+1, &rset, &wset, NULL, NULL);
	if (ret == -1)
	{
	    where = "select_nosignal()";
	    goto panic;
	}
	init_msg_queue(&tmp);
	init_msg_queue(&to_krn);

	while ((mptr = msg_dequeue(&wpenq)) != NULL)
	{
	    if (FD_ISSET(mptr->type.io.io_socket, &wset)) {
		io_ret = senddata(mptr->type.io.io_socket,
				 &mptr->mb.mbq,
				 &no_sent, DISCARD_TRUE);
		
		if (io_ret > 0 && no_sent.size == 0) {
		    mptr->type.io.io_opt = IO_OPT_WRITE;
		    mptr->type.io.io_ret = IO_RET_SUCCESS;
		    mptr->type.io.io_errno   = 0;
		    mptr->type.io.io_rep_len += io_ret;

		    mptr->msg_type = MSG_IO_REPLY;

		    msg_enqueue(&to_krn, mptr);
		}
		else if ( io_ret == -1 ) {
		    mptr->type.io.io_opt = IO_OPT_WRITE;
		    mptr->type.io.io_ret = IO_RET_FAILURE;
		    mptr->type.io.io_errno = errno;
		
		    mptr->msg_type = MSG_IO_REPLY;
		    mbuffmove(&(mptr->mb.mbq), &no_sent);
		    msg_enqueue(&to_krn, mptr);
		}
		else {
		    mptr->type.io.io_rep_len += io_ret;
		    mbuffmove(&(mptr->mb.mbq), &no_sent);
		    msg_enqueue(&tmp, mptr);
		}
	    }
	    else
		msg_enqueue(&tmp, mptr);
	}
	msgmove(&wpenq, &tmp);

	init_msg_queue(&tmp);

	while ((mptr = msg_dequeue(&rpenq)) != NULL)
	{
	    if (FD_ISSET(mptr->type.io.io_socket, &rset)) {
		io_ret = recvdata(mptr->type.io.io_socket,
				 &(mptr->mb.mbq),
				 mptr->type.io.io_req_len, mptr->type.io.io_chunk_size);
		
		if (io_ret > 0) {
		    mptr->type.io.io_opt = IO_OPT_READ;
		    mptr->type.io.io_ret = IO_RET_SUCCESS;
		    mptr->type.io.io_errno   = 0;
		    mptr->type.io.io_rep_len = io_ret;

		    mptr->msg_type = MSG_IO_REPLY;

		    msg_enqueue(&to_krn, mptr);
		}
		else if ( io_ret == -1 ) {
		    mptr->type.io.io_opt = IO_OPT_READ;
		    mptr->type.io.io_ret = IO_RET_FAILURE;
		    mptr->type.io.io_errno = errno;
		    mptr->msg_type = MSG_IO_REPLY;
		    msg_enqueue(&to_krn, mptr);
		}
		else {
		    msg_enqueue(&tmp, mptr);
		}
	    }
	    else
		msg_enqueue(&tmp, mptr);
	}
	msgmove(&rpenq, &tmp);

	init_msg_queue(&tmp);

	/*
	 * Look for new request
	 */
	if (FD_ISSET(itc_event, &rset)) 
	{
	    ret = itc_read_event(itc_event, &ieinfo);
	    if (ret == -1)
	    {
		where = "itc_read_event()";
		goto panic;
	    }

	    if (ieinfo.src != KERNEL_LAYER_THREAD)
	    {
		where = "[itc wrong src]";
		goto panic;
	    }
	    
	    itc_readfrom(KERNEL_LAYER_THREAD,
		         &tmp,
			 0);

	    while( (mptr = msg_dequeue(&tmp)) != NULL)
	    {
		if (mptr->msg_type != MSG_IO_REQUEST)
		    /* Drop silently */
		    continue;
		mptr->type.io.io_ret     = 0;
		mptr->type.io.io_errno   = 0;
		mptr->type.io.io_rep_len = 0;
		if (mptr->type.io.io_opt == IO_OPT_READ)
		    msg_enqueue(&rpenq, mptr);
		if (mptr->type.io.io_opt == IO_OPT_WRITE)
		    msg_enqueue(&wpenq, mptr);
	    }
	}

	/*
         * Send the reply to the kernel
	 */
	if (to_krn.size != 0)
	    itc_writeto(KERNEL_LAYER_THREAD,
			&to_krn,
			0);
    }

panic:
    PANIC(errno,"DATAIO_LAYER_THREAD",where);
    return NULL;
}
Example #11
0
int main(int argc, char *argv[]) {
    if (argc < 3) { // Checking for correct arquments
        printf("Useage: dhtnode own_hostname own_port\n");
        exit(0);
    }
    char* my_url = argv[1];
    char* my_port = argv[2];
    
    sha1_t my_hash; // Create hash for own address
    hash_url(my_url, my_port, my_hash);
    fd_set master;
    fd_set rfds;
    int retval;
    int running = 1;
    int listensock = create_listen_socket(my_port);
    con_t server;
    memset(&server,0,sizeof server);
    con_t left;
    memset(&left,0,sizeof left);
    con_t right;
    memset(&right,0,sizeof right);
    FD_SET(STDIN_FILENO, &master);
    FD_SET(listensock, &master);
    
    int fdmax = listensock;
    struct timeval looptime;

    while (running) {
        looptime.tv_sec = 1;
        looptime.tv_usec = 0;
        rfds = master;
        retval = select(fdmax + 1, &rfds, NULL, NULL, &looptime);

        if (retval == -1)
            die("select failed");
        else if (retval) {
            if (FD_ISSET(STDIN_FILENO, &rfds)) {
                int argcount;
                char** arguments = NULL;
                int cmd = getcommand(STDIN_FILENO, &argcount, &arguments);
                printf("got command\n");
                if (cmd < 0) {
                    //TODO handle different errors differently
                    printf("error: %d\n", cmd);
                    exit(-1);
                }
                switch (cmd) {
                    case USER_EXIT:
                        if(server.state != ST_EMPTY && (argcount == 0 || strcmp(arguments[0],"force"))){//remember strcmp returns 0 on match
                            printf("trying to exit\n");
                            send_dht_pckt(server.socket,DHT_DEREGISTER_BEGIN,my_hash,my_hash,0,NULL);
                        }
                        else{
                            printf("exiting\n");
                            running = 0;
                        }
                        freeargs(argcount, arguments);
                        break;
                    case USER_CONNECT:
                        if(argcount != 2){
                            printf("usage: connect url port\n");
                            freeargs(argcount,arguments);
                            break;
                        }
                        if(server.state != ST_EMPTY){
                            printf("Already connected to the server. Use exit to disconnect.\n");
                            freeargs(argcount,arguments);
                            break;
                        }
                        printf("connecting to %s:%s\n", arguments[0], arguments[1]);
                        int sock = create_connection(arguments[0], arguments[1]);
                        printf("connection made\n");
                        FD_SET(sock, &master);
                        if(sock > fdmax) fdmax = sock;
                        server.socket = sock;
                        server.state = ST_WF_SER_SHAKE;
                        
                        freeargs(argcount, arguments);
                        break;
                    case USER_PRINT:
                        printf("printing...\n");
                        for(int i = 0; i < argcount; i++){
                            printf("%s:\n",arguments[i]);
                            if(!strcmp(arguments[i],"sockets")){
                               printf("server, %d %s\n",server.socket,(server.socket != 0 && FD_ISSET(server.socket,&master))? "is set":"not set"); 
                               printf("right, %d %s\n",right.socket,(right.socket != 0 && FD_ISSET(right.socket,&master))? "is set":"not set"); 
                               printf("left, %d %s\n",left.socket,(left.socket != 0 && FD_ISSET(left.socket,&master))? "is set":"not set"); 
                            }
                            else if(!strcmp(arguments[i],"states")){
                                printf("server, %d\n",server.state);
                                printf("right, %d\n",right.state);
                                printf("left, %d\n",left.state);
                            }
                        }
                        freeargs(argcount,arguments);
                        break;
                    case USER_UNKNW_CMD:
                        printf("unknown command, line was:");
                        for (int i = 0; i < argcount; i++) {
                            printf(" %s", arguments[i]);
                        }
                        printf("\n");
                        freeargs(argcount, arguments);
                        break;
                }
            }
            //check for new connections
            if (FD_ISSET(listensock, &rfds)) {
                printf("someone is connecting\n");
                if(right.state == ST_EMPTY){
                    right.socket = accept_connection(listensock);
                    if(right.socket < 0){
                        die(strerror(errno));
                    }
                    FD_SET(right.socket, &master);
                    if(right.socket > fdmax) fdmax = right.socket;
                    right.state = ST_WF_CLI_SHAKE;
                } else if (left.state == ST_EMPTY) {
                    left.socket = accept_connection(listensock);
                    if(left.socket < 0){
                        die(strerror(errno));
                    }
                    FD_SET(left.socket, &master);
                    if(left.socket > fdmax) fdmax = left.socket;
                    left.state = ST_WF_CLI_SHAKE;
                }
            }
            //check for msg from server
            if(server.state != ST_EMPTY && FD_ISSET(server.socket, &rfds)){
                int status;
                if(server.state == ST_WF_SER_SHAKE){
                    printf("getting shake\n");
                    status = recvdata(server.socket, NULL);
                    if(status == NTW_SERVER_SHAKE){
                        printf("shaking back\n");
                        send_shake(server.socket, NTW_CLIENT_SHAKE);
                        unsigned char formated_url[strlen(my_url)+3];
                        format_url(my_url, my_port, formated_url);
                        printf("sending DHT_REGISTER_BEGIN\n");
                        send_dht_pckt(server.socket,DHT_REGISTER_BEGIN,my_hash,my_hash,strlen(my_url)+3,formated_url);
                        server.state = ST_ONLINE;
                    }
                    //TODO error handling
                    /*On correct shake shake back and send DHT_REGISTER_BEGIN
                     with our sha1 as sender and target and
                     our port+url as payload
                     switch state to ST_ONLINE*/
                } else{
                    DHT_t packet;
                    memset(&packet, 0, sizeof packet);
                    status = recvdata(server.socket, &packet);
                    if(status != NTW_PACKET_OK){
                        switch(status){
                            case NTW_ERR_SERIOUS:
                                die(strerror(errno));
                                break;
                            case NTW_DISCONNECT:
                                die("server disconnected");
                                break;
                            default:
                                printf("getting packet failed somehow\n");
                                memset(&packet, 0, sizeof packet);
                                break;
                        }
                    }
                    printf("received from server:\n");
                    print_dht_packet(&packet);
                    //TODO error handling
                    uint16_t reqt = ntohs(packet.req_type);
                    if(server.state == ST_ONLINE && reqt == DHT_REGISTER_FAKE_ACK){
                        printf("fake ack received\n");
                        /*send DHT_REGISTER_DONE to server
                         target and sender are both our hash
                         state to ST_IDLING*/
                        int a = send_dht_pckt(server.socket, DHT_REGISTER_DONE, my_hash, my_hash, 0, NULL);
                        if(a == 0) server.state = ST_IDLING;
                        else exit(1); // or error handling
                        
                    } else if(server.state == ST_IDLING && reqt == DHT_REGISTER_BEGIN){
                        printf("dht_register_begin received\n");
                        /*open connection to the new node
                         which port+url is in packet and
                         send data + DHT_REGISTER_ACK
                         our hash sender and target
                         state to ST_WF_REG_DONE*/
                        char his_url[packet.pl_length-2];
                        strcpy(his_url,(char*)packet.payload+2);
                        uint16_t* port = (uint16_t*)packet.payload;
                        *port = ntohs(*port);
                        char his_port[10];
                        sprintf(his_port,"%u",*port);
                        int sock = create_connection(his_url,his_port);
                        FD_SET(sock, &master);
                        if(sock > fdmax) fdmax = sock;
                        con_t* pal;
                        pal = (right.state == ST_EMPTY) ? &right : &left;
                        memcpy(pal->hash,packet.sender,20);
                        pal->socket = sock;
                        pal->state = ST_WF_SER_SHAKE;
                        //server.state = ST_WF_REG_DONE;
                        
                    } else if(server.state == ST_IDLING && reqt == DHT_REGISTER_DONE){
                        printf("received reg done\n");
                        //server.state = ST_IDLING;
                        /*dump old data and return to ST_IDLING*/
                    } else if(server.state == ST_IDLING && reqt == DHT_DEREGISTER_ACK){
                        printf("dereg ack received\n");
                        /*open connection to neighbours their urls are as
                         payload of the package and send data and
                         DHT_DEREGISTER_BEGIN (our hash as sender and target)
                         change to ST_WF_DEREG_DONE*/
                        uint16_t port_buf = ((uint16_t*)packet.payload)[0];
                        port_buf = ntohs(port_buf);
                        char port1[10];
                        sprintf(port1,"%u",port_buf);
                        char url1[30];
                        strcpy(url1,(char*)(packet.payload+2));
                        
                        port_buf = ((uint16_t*)(packet.payload+3+strlen(url1)))[0];
                        port_buf = ntohs(port_buf);
                        char port2[10];
                        sprintf(port2,"%u",port_buf);
                        char url2[30];
                        strcpy(url2,(char*)(packet.payload+5+strlen(url1)));
                        printf("parsing got:\nurl1 = %s:%s\nurl2 = %s:%s\n", url1, port1, url2, port2);
                        
                        //connect to right neighbour
                        right.socket = create_connection(url1,port1);
                        FD_SET(right.socket, &master);
                        if(right.socket > fdmax) fdmax = right.socket;
                        hash_url(url1,port1,right.hash);
                        right.state = ST_WF_SER_SHAKE;
                        //connect to left neighbour
                        left.socket = create_connection(url2,port2);
                        FD_SET(left.socket, &master);
                        if(left.socket > fdmax) fdmax = left.socket;
                        hash_url(url2,port2,left.hash);
                        left.state = ST_WF_SER_SHAKE;
                        
                        server.state = ST_WF_DEREG_DONE;
                    } else if(server.state == ST_IDLING && reqt == DHT_DEREGISTER_DENY){
                        printf("dereg deny received\n");
                        /*tell user that leaving is impossible
                         return to ST_IDLING*/
                        printf("Unable to exit. You are the last node. To over-ride this use exit force command.\n");
                        server.state = ST_IDLING;
                    } else if(server.state == ST_WF_DEREG_DONE && reqt == DHT_DEREGISTER_DONE){
                        if(right.state == ST_DEREG_DATA_SENT && !memcmp(right.hash, packet.sender, 20)){
                            FD_CLR(right.socket, &master);
                            close(right.socket);
                            memset(&right,0,sizeof right);
                        }
                        else if(left.state == ST_DEREG_DATA_SENT && !memcmp(left.hash, packet.sender, 20)){
                            FD_CLR(left.socket, &master);
                            close(left.socket);
                            memset(&left,0,sizeof left);
                        }
                        if(left.state == ST_EMPTY && right.state == ST_EMPTY){
                            printf("leaving the network\n");
                            close(server.socket);
                            FD_CLR(server.socket, &master);
                            memset(&server,0,sizeof server);
                            printf("left the network\n");
                        }
                        /*close the connection to server
                         state to ST_EMPTY*/
                        }
                    }
                }
            }
            for(int i = 0; i<2;i++){
                con_t* neighbour = (i == 0) ? &right : &left;
            //check for msg from right and left neighbour
            if(neighbour->state != ST_EMPTY && FD_ISSET(neighbour->socket, &rfds)){
                int status;
                if(neighbour->state == ST_WF_CLI_SHAKE){
                    /* prepare to receive data
                     switch state to ST_RCV_DATA_REG or
                     ST_RCV_DATA_DEREG depending on server state*/
                    status = recvdata(neighbour->socket, NULL);
                    if(status == NTW_CLIENT_SHAKE){
                        if(server.state == ST_ONLINE){
                            neighbour->state = ST_RCV_DATA_REG;
                        }
                        if(server.state == ST_IDLING){ 
                            neighbour->state = ST_RCV_DATA_DEREG;
                        }
                    } else {
                        switch(status){
                            case NTW_ERR_SERIOUS:
                                die(strerror(errno));
                                break;
                            case NTW_DISCONNECT:
                                printf("%s disconnected\n",(i)?"left":"right");
                                FD_CLR(neighbour->socket,&master);
                                memset(neighbour,0,sizeof *neighbour);
                                break;
                            default:
                                printf("getting shake failed somehow\n");
                                break;
                        }
                    }
                } else if (neighbour->state == ST_WF_SER_SHAKE){
                    /* answer with client shake and pump your data to the neighbour
                     after that send DHT_REGISTER_ACK or DHT_DEREG_BEGIN
                     either way after this the connection to neighbour can be disconnected*/
                    status = recvdata(neighbour->socket, NULL);
                    if(status == NTW_SERVER_SHAKE){
                        printf("shaking back\n");
                        send_shake(neighbour->socket, NTW_CLIENT_SHAKE);
                        if(server.state == ST_IDLING){ //we should end with DHT_REGISTER_ACK
                            send_dht_pckt(neighbour->socket,DHT_REGISTER_ACK,my_hash,my_hash,0,NULL);
                            FD_CLR(neighbour->socket, &master);
                            close(neighbour->socket);
                            memset(neighbour,0,sizeof *neighbour);
                        }
                        if(server.state == ST_WF_DEREG_DONE){ //we should end with DHT_DEREGISTER_BEGIN
                            send_dht_pckt(neighbour->socket,DHT_DEREGISTER_BEGIN,my_hash,my_hash,0,NULL);
                            FD_CLR(neighbour->socket, &master);
                            close(neighbour->socket);
                            neighbour->state = ST_DEREG_DATA_SENT;
                        }
                    } else {
                        switch(status){
                            case NTW_ERR_SERIOUS:
                                die(strerror(errno));
                                break;
                            case NTW_DISCONNECT:
                                die("neighbour disconnected");
                                break;
                            default:
                                printf("getting shake failed somehow\n");
                                break;
                        }
                    }
                    
                } else{
                    DHT_t packet;
                    memset(&packet, 0, sizeof packet);
                    status = recvdata(neighbour->socket, &packet);
                    printf("received package from %s:\n",(i)?"left":"right");
                    print_dht_packet(&packet);
                    if(status != NTW_PACKET_OK){
                        switch(status){
                            case NTW_ERR_SERIOUS:
                                die(strerror(errno));
                                break;
                            case NTW_DISCONNECT:
                                printf("%s neighbour disconnected.\n",(i)?"left":"right");
                                FD_CLR(neighbour->socket,&master);
                                close(neighbour->socket);
                                memset(neighbour,0,sizeof * neighbour);
                                break;
                            case NTW_ERR_TIMEOUT:
                                printf("package from %s timed out!\n",(i)?"left":"right");
                                memset(&packet,0,sizeof packet);
                                break;
                        }
                    }
                    uint16_t reqt = ntohs(packet.req_type);
                    if(neighbour->state == ST_RCV_DATA_REG && reqt == DHT_REGISTER_ACK){
                        /*all data is now received */
                        FD_CLR(neighbour->socket, &master);
                        close(neighbour->socket);
                        memset(neighbour,0,sizeof *neighbour);
                        neighbour->state = ST_REG_DATA_RCVD;
                        if(right.state == ST_REG_DATA_RCVD && left.state == ST_REG_DATA_RCVD){
                            send_dht_pckt(server.socket, DHT_REGISTER_DONE, my_hash, my_hash, 0, NULL);
                            right.state = ST_EMPTY;
                            left.state = ST_EMPTY;
                            server.state = ST_IDLING;
                        }
                    } else if(neighbour->state == ST_RCV_DATA_DEREG && reqt == DHT_DEREGISTER_BEGIN){
                        send_dht_pckt(server.socket, DHT_DEREGISTER_DONE, packet.sender, my_hash, 0, NULL);
                        FD_CLR(neighbour->socket, &master);
                        close(neighbour->socket);
                        memset(neighbour,0,sizeof *neighbour);
                    }
                }
            }
        }
    }

    close(listensock);

    return 0;
}
Example #12
0
/* Fetch data, check if it's data for us and whether it's useable or not. If not, return 
 * a failure code so we can delete this server from our list and continue with another one. 
 */
int 
recvpkt (
		SOCKET rsock,
		struct pkt *rpkt,
		struct pkt *spkt
	)
{
	sockaddr_u sender;
	char *rdata /* , done */;

	register int a;
	int has_mac, is_authentic, pkt_len, orig_pkt_len;


	/* Much space, just to be sure */
	rdata = emalloc(sizeof(char) * 256);

	pkt_len = recvdata(rsock, &sender, rdata, 256);

#if 0	/* done uninitialized */
	if (!done) {
		/* Do something about it, first check for a maximum length of ntp packets,
		 * probably that's something we can avoid 
		 */
	}
#endif
	
	if (pkt_len < 0) {
		if (ENABLED_OPT(NORMALVERBOSE)) {
			printf("sntp recvpkt failed: %d.\n", pkt_len);
		}
		free(rdata);
		return pkt_len;
	}
	
	/* Some checks to see if that packet is intended for us */

	/* No MAC, no authentication */
	if (LEN_PKT_NOMAC == pkt_len)
		has_mac = 0;

	/* If there's more than just the NTP packet it should be a MAC */	
	else if (pkt_len > LEN_PKT_NOMAC) 
		has_mac = pkt_len - LEN_PKT_NOMAC;
	
	else {
		if (ENABLED_OPT(NORMALVERBOSE))
			printf("sntp recvpkt: Funny packet length: %i. Discarding package.\n", pkt_len);
		free(rdata);

		return PACKET_UNUSEABLE;
	}

	/* Packet too big */
	if (pkt_len > LEN_PKT_MAC) {
		if (ENABLED_OPT(NORMALVERBOSE))
			printf("sntp recvpkt: Received packet is too big (%i bytes), trying again to get a useable packet\n", 
					pkt_len);
		free(rdata);

		return PACKET_UNUSEABLE;
	}

	orig_pkt_len = pkt_len;
	pkt_len = min(pkt_len, sizeof(struct pkt));
	
	for (a = 0; a < pkt_len; a++) 
		/* FIXME! */
		if (a < orig_pkt_len)
			((char *) rpkt)[a] = rdata[a];
		else
			((char *) rpkt)[a] = 0;

	free(rdata);
	rdata = NULL;

	/* MAC could be useable for us */
	if (has_mac) {
		/* Two more things that the MAC must conform to */
		if(has_mac > MAX_MAC_LEN || has_mac % 4 != 0) {
			is_authentic = 0; /* Or should we discard this packet? */
		}
		else {
			if (MAX_MAC_LEN == has_mac) {
				struct key *pkt_key = NULL;
				
				/*
				 * Look for the key used by the server in the specified keyfile
				 * and if existent, fetch it or else leave the pointer untouched 
				 */
				get_key(rpkt->mac[0], &pkt_key);

				/* Seems like we've got a key with matching keyid */
				if (pkt_key != NULL) {
					/*
					 * Generate a md5sum of the packet with the key from our keyfile
					 * and compare those md5sums 
					 */
					if (!auth_md5((char *) rpkt, has_mac, pkt_key)) {
						if (ENABLED_OPT(AUTHENTICATION)) {
							/* We want a authenticated packet */
							if (ENABLED_OPT(NORMALVERBOSE)) {
								char *hostname = ss_to_str(&sender);
								printf("sntp recvpkt: Broadcast packet received from %s is not authentic. Will discard this packet.\n", 
										hostname);

								free(hostname);
							}
							return SERVER_AUTH_FAIL;
						}
						else {
							/* 
							 * We don't know if the user wanted authentication so let's 
							 * use it anyways 
							 */
							if (ENABLED_OPT(NORMALVERBOSE)) {
								char *hostname = ss_to_str(&sender);
								printf("sntp recvpkt: Broadcast packet received from %s is not authentic. Authentication not enforced.\n", 
										hostname);

								free(hostname);
							}

							is_authentic = 0;
						}
					}
					else {
						/* Yay! Things worked out! */
						if (ENABLED_OPT(NORMALVERBOSE)) {
							char *hostname = ss_to_str(&sender);
							printf("sntp recvpkt: Broadcast packet received from %s successfully authenticated using key id %i.\n", 
									hostname, rpkt->mac[0]);

							free(hostname);
						}

						is_authentic = 1;
					}
				}
			}
		}
	}

	/* Check for server's ntp version */
	if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION ||
	    PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) {
		if (ENABLED_OPT(NORMALVERBOSE))
			printf("sntp recvpkt: Packet got wrong version (%i)\n", PKT_VERSION(rpkt->li_vn_mode));

		return SERVER_UNUSEABLE;
	} 

	/* We want a server to sync with */
	if (PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER &&
	    PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE) {
		if (ENABLED_OPT(NORMALVERBOSE))
			printf("sntp recvpkt: mode %d stratum %i\n",
			   PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);

		return SERVER_UNUSEABLE;
	}

	/* Stratum is unspecified (0) check what's going on */
	if (STRATUM_PKT_UNSPEC == rpkt->stratum) {
		char *ref_char;

		if (ENABLED_OPT(NORMALVERBOSE))
			printf("sntp recvpkt: Stratum unspecified, going to check for KOD (stratum: %i)\n", rpkt->stratum);


		ref_char = (char *) &rpkt->refid;

		if (ENABLED_OPT(NORMALVERBOSE)) 
			printf("sntp recvpkt: Packet refid: %c%c%c%c\n", ref_char[0], ref_char[1], ref_char[2], ref_char[3]);
		
		/* If it's a KOD packet we'll just use the KOD information */
		if (ref_char[0] != 'X') {
			if (!strncmp(ref_char, "DENY", 4))
				return KOD_DEMOBILIZE;

			if (!strncmp(ref_char, "RSTR", 4))
				return KOD_DEMOBILIZE;

			if (!strncmp(ref_char, "RATE", 4))
				return KOD_RATE;

			/* There are other interesting kiss codes which might be interesting for authentication */
		}
	}

	/* If the server is not synced it's not really useable for us */
	if (LEAP_NOTINSYNC == PKT_LEAP(rpkt->li_vn_mode)) {
		if (ENABLED_OPT(NORMALVERBOSE)) 
			printf("sntp recvpkt: Server not in sync, skipping this server\n");

		return SERVER_UNUSEABLE;
	}

	/*
	 * Decode the org timestamp and make sure we're getting a response
	 * to our last request. 
	 */

#ifdef DEBUG
	printf("rpkt->org:\n");
	l_fp_output(&rpkt->org, stdout);
	printf("spkt->xmt:\n");
	l_fp_output(&spkt->xmt, stdout);
#endif
	
	if (!L_ISEQU(&rpkt->org, &spkt->xmt)) {
		if (ENABLED_OPT(NORMALVERBOSE))
			printf("sntp recvpkt: pkt.org and peer.xmt differ\n");
		
		return PACKET_UNUSEABLE;
	}

	return pkt_len;
}
int networkthink()
{

	char netrecbuffer[NETBUFFER_SIZE];

	
	int msgsize = 0;
	unsigned short port = 0;
	char charip[25] = { 0 };

	char*worked = net.Receive(&msgsize, &port, charip, netrecbuffer, NETBUFFER_SIZE);

	if (!msgsize)
		return 0;

	if (!strstr(serverip, charip))
	{
		printf("ip mismatch??\n");
		return 0;
	}

	bf_read recvdata(netrecbuffer, msgsize);
	int header = recvdata.ReadLong();

	int connection_less = 0;

	if (header == NET_HEADER_FLAG_QUERY)
		connection_less = 1;

	if (header == NET_HEADER_FLAG_SPLITPACKET)
	{
		printf("SPLIT\n");

		if (!netchan->HandleSplitPacket(netrecbuffer, msgsize, recvdata))
			return 0;

		header = recvdata.ReadLong();
	}

	if (header == NET_HEADER_FLAG_COMPRESSEDPACKET)
	{
		unsigned int uncompressedSize = msgsize * 16;

		char*tmpbuffer = new char[uncompressedSize];


		memmove(netrecbuffer, netrecbuffer + 4, msgsize + 4);

		NET_BufferToBufferDecompress(tmpbuffer, uncompressedSize, netrecbuffer, msgsize);

		memcpy(netrecbuffer, tmpbuffer, uncompressedSize);


		recvdata.StartReading(netrecbuffer, uncompressedSize, 0);
		printf(".");


		delete[] tmpbuffer;
		tmpbuffer = 0;
	}


	recvdata.Reset();


	if (connection_less)
	{
		return HandleConnectionLessPacket(charip, port, connection_less, recvdata);
	}

	int flags = netchan->ProcessPacketHeader(msgsize, recvdata);

	if (flags == -1)
	{

		printf("Malformed package!\n");

		return 0;
	}


	last_packet_received = clock();

	if (flags & PACKET_FLAG_RELIABLE)
	{
		int i = 0;

		int bit = recvdata.ReadUBitLong(3);
		bit = 1 << bit;

		for (i = 0; i<MAX_STREAMS; i++)
		{

			if (recvdata.ReadOneBit() != 0)
			{
				if (!netchan->ReadSubChannelData(recvdata, i))
				{
					return 0;
				}
			}
		}


		FLIPBIT(netchan->m_nInReliableState, bit);

		for (i = 0; i<MAX_STREAMS; i++)
		{
			if (!netchan->CheckReceivingList(i))
			{
				return 0;
			}
		}
	}



	if (recvdata.GetNumBitsLeft() > 0)
	{
		int proc = ProcessMessages(recvdata);



	}

	static bool neededfragments = false;

	if (netchan->NeedsFragments() || flags&PACKET_FLAG_TABLES)
	{
		neededfragments = true;
		NET_RequestFragments();
	}

	return 0;
}