void ServiceUDP(int sock) {
   static char buf[32767];
   int rc;
   int asize, len;
   struct sockaddr_in client;

   // Receive the packet

   asize = sizeof(client);
   len = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&client,
                  &asize);
   if (len == -1) {
      psock_errno("recvfrom()");
      exit(1);
   }

   printf("Received a UDP echo request from %s port %d\n",
          inet_ntoa(client.sin_addr), ntohs(client.sin_port));

   // Echo it back

   rc = sendto(sock, buf, len, 0, (struct sockaddr *)&client, sizeof(client));
   if (rc == -1 || rc != len) {
      psock_errno("sendto()");
      exit(1);
   }
}
Exemplo n.º 2
0
extern int net_send_data(int sock, char * buff, int buffsize, int * pos, int * currsize)
{
	int	nsend;

	ASSERT(buff,-1);
	ASSERT(pos,-1);
	if (*pos>buffsize) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] send buffer overflow pos=%d buffsize=%d",sock,*pos,buffsize);
		return -1;
	}
	if (*currsize>*pos) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] send buffer error currsize=%d pos=%d",sock,*currsize,*pos);
		return -1;
	}
	nsend=psock_send(sock,buff+*pos-*currsize,*currsize,0);
	if (nsend==0) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] no data sent (close connection)",sock);
		return -1;
	}
	if (nsend<0) {
		if (
#ifdef PSOCK_EINTR
			psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
			psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
			psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_NOBUFS
			psock_errno()==PSOCK_ENOBUFS ||
#endif
#ifdef PSOCK_ENOMEM
			psock_errno()==ENOMEM ||
#endif
		0)
			return 0;

		eventlog(eventlog_level_error,__FUNCTION__,"[%d] error sent data (closing connection) (psock_send: %s)",sock,pstrerror(psock_errno()));
		return -1;
	}
	*currsize -= nsend;
	return 1;
}
Exemplo n.º 3
0
/*------------------------------------------------------------------
 * psock_errno()
 *------------------------------------------------------------------*/
RexxRoutine1(CSTRING, SockPSock_Errno, OPTIONAL_CSTRING, type)
{
    if (type == NULL)
    {
        type = "";
    }
    psock_errno(type);
    return "";
}
Exemplo n.º 4
0
extern int net_recv_data(int sock, char * buff, int buffsize, int * pos, int * currsize)
{
	int	nrecv;

	ASSERT(buff,-1);
	ASSERT(pos,-1);
	if (*pos>buffsize) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] recv buffer overflow pos=%d buffsize=%d",sock,*pos,buffsize);
		return -1;
	}
	if (*currsize>*pos) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] recv buffer error currsize=%d pos=%d",sock,*currsize,*pos);
		return -1;
	}
	if (*pos==buffsize) {
		std::memmove(buff,buff+*pos,*currsize);
		*pos=0;
	}
	nrecv=psock_recv(sock,buff+*pos,buffsize-*pos,0);
	if (nrecv==0) {
		eventlog(eventlog_level_info,__FUNCTION__,"[%d] remote host closed connection",sock);
		return -1;
	}
	if (nrecv<0) {
		if (
#ifdef PSOCK_EINTR
			psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
			psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
			psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ENOMEM
			psock_errno()==ENOMEM ||
#endif
		0)
			return 0;

		if (
#ifdef PSOCK_ENOTCONN
			psock_errno()==PSOCK_ENOTCONN ||
#endif
#ifdef PSOCK_ECONNRESET
			psock_errno()==PSOCK_ECONNRESET ||
#endif
		0) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] remote host closed connection (psock_recv: %s)",sock,pstrerror(psock_errno()));
		return -1;
		}
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] recv error (closing connection) (psock_recv: %s)",sock,pstrerror(psock_errno()));
		return -1;
	}
	* currsize += nrecv;
	return 1;
}
void ServiceTCP(void *arg) {
   int rc, len;
   char buf[1024];
   int sock;

   // Convert the parameter to something we can use

   sock = (int)arg;

   // Do this until the client closes the connection

   while (1) {

      // Wait until there's some data available

      len = recv(sock, buf, sizeof(buf), 0);
      if (len == -1) {
         psock_errno("recv()");
         exit(1);
      }

      if (len == 0) {
         printf("TCP socket %d: The client broke the connection\n", sock);
         break;
      }

      printf("TCP socket %d: received %d bytes\n", sock, len);

      // Send the data back

      rc = send(sock, buf, len, 0);
      if (rc == -1) {
         psock_errno("send()");
         exit(1);
      }
   }
}
Exemplo n.º 6
0
extern int net_send(int sock, const void *buff, int len)
{
    int res;

    res = psock_send(sock, buff, len, 0);

    if (res > 0) return res;
    if (!res) return -1;

    if (
#ifdef PSOCK_EINTR
	psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
	psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
	psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ENOBUFS
	psock_errno()==PSOCK_ENOBUFS ||
#endif
#ifdef PSOCK_ENOMEM
	psock_errno()==PSOCK_ENOMEM ||
#endif
	0)
	return 0; /* try again later */

    if (
#ifdef PSOCK_EPIPE
	psock_errno()!=PSOCK_EPIPE &&
#endif
#ifdef PSOCK_ECONNRESET
	psock_errno()!=PSOCK_ECONNRESET &&
#endif
	1) eventlog(eventlog_level_debug,__FUNCTION__,"[%d] could not send data (closing connection) (psock_send: %s)",sock,std::strerror(psock_errno()));

    return -1;
}
Exemplo n.º 7
0
extern int net_recv(int sock, void *buff, int len)
{
    int res;

    res = psock_recv(sock, buff, len, 0);
    if (res > 0) return res;
    if (!res) return -1;	/* connection closed */

    if (
#ifdef PSOCK_EINTR
	psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
	psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
	psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ENOMEM
	psock_errno()==PSOCK_ENOMEM ||
#endif
	0) /* try later */
        return 0;

    if (
#ifdef PSOCK_ENOTCONN
	psock_errno()==PSOCK_ENOTCONN ||
#endif
#ifdef PSOCK_ECONNRESET
	psock_errno()==PSOCK_ECONNRESET ||
#endif
	0) {
/*	    eventlog(eventlog_level_debug,__FUNCTION__,"[%d] remote host closed connection (psock_recv: %s)",sock,std::strerror(psock_errno())); */
	    return -1; /* common error: close connection, but no message */
    }

    eventlog(eventlog_level_debug,__FUNCTION__,"[%d] receive error (closing connection) (psock_recv: %s)",sock,std::strerror(psock_errno()));
    return -1;
}
int main(int argc, char *argv[])
{
   int port;
   int accexcnt=0, count;
   int tid=0;
   int rv;
   struct sockaddr_in serv_addr;
   char q;
   struct timeval tv;


if( argc < 3) {
   printf("Usage: %s [server port] [number of acceptex threads]\n", argv[0]);
   return -1;
}

   port = (unsigned int) atoi(argv[1]);
   accexcnt = atoi(argv[2]);

   if ( (sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
   {
     printf("server : can't open stream socket");
     exit(0);
   }

   printf("Server: socket opened %d\n",sockfd);
   memset((char *) &serv_addr,0, sizeof(serv_addr));
   serv_addr.sin_family      = AF_INET ;
   serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
   serv_addr.sin_port        = htons(port);


  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)  {
       printf("server : can't bind local address");
       exit (-1);
  }
  printf("Server: socket bound %d\n",sockfd);

  tv.tv_sec = 10;
  tv.tv_usec = 0;

  rv = setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&tv,sizeof(struct timeval));
  if( rv < 0) psock_errno( " Set SO_RCVTIMEO");


  listen(sockfd, 5);
  printf("now listening\n");

  printf("Creating threads\n");
  printf("ENTER THE VARIABLE Q \n");
  scanf("%c",&q);

  for( count =0; count < accexcnt; count++)
  {
    if( (tid = _beginthread(acceptex_thread, NULL, 8192, NULL)) < 0)
    {
       printf("error\n");
       exit(1);
    }
    printf("Acceptex Thread Id is: %x\n",tid);
  }


  while( total_threads < accexcnt )
     DosSleep( 1 );

    soclose(sockfd);
   return 1;

}
Exemplo n.º 9
0
extern int main(int argc, char * argv[])
{
    int                a;
    int                sd;
    struct sockaddr_in saddr;
    t_packet *         packet;
    t_packet *         rpacket;
    t_packet *         fpacket;
    char const *       clienttag=NULL;
    char const *       archtag=NULL;
    char const *       servname=NULL;
    unsigned short     servport=0;
    char const *       hexfile=NULL;
    char               text[MAX_MESSAGE_LEN];
    char const *       reqfile=NULL;
    struct hostent *   host;
    unsigned int       commpos;
    struct termios     in_attr_old;
    struct termios     in_attr_new;
    int                changed_in;
    unsigned int       currsize;
    unsigned int       filelen;
    unsigned int       startoffset;
    int                startoffsetoverride=0;
#define EXIST_ACTION_UNSPEC    -1
#define EXIST_ACTION_ASK        0
#define EXIST_ACTION_OVERWRITE  1
#define EXIST_ACTION_BACKUP     2
#define EXIST_ACTION_RESUME     3 
    int		       exist_action=EXIST_ACTION_UNSPEC;
    struct stat        exist_buf;
    char const *       filename;
    FILE *             fp;
    FILE *             hexstrm=NULL;
    int                fd_stdin;
    t_bnettime         bntime;
    time_t             tm;
    char               timestr[FILE_TIME_MAXLEN];
    unsigned int       screen_width,screen_height;
    int                munged;

    if (argc<1 || !argv || !argv[0])
    {
	fprintf(stderr,"bad arguments\n");
	return STATUS_FAILURE;
    }
    
    for (a=1; a<argc; a++)
	if (servname && isdigit((int)argv[a][0]) && a+1>=argc)
	{
            if (str_to_ushort(argv[a],&servport)<0)
            {
                fprintf(stderr,"%s: \"%s\" should be a positive integer\n",argv[0],argv[a]);
                usage(argv[0]);
            }
	}
	else if (!servname && argv[a][0]!='-' && a+2>=argc)
	    servname = argv[a];
        else if (strcmp(argv[a],"-b")==0 || strcmp(argv[a],"--client=SEXP")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_BROODWARS;
        }
        else if (strcmp(argv[a],"-d")==0 || strcmp(argv[a],"--client=DRTL")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_DIABLORTL;
        }
        else if (strcmp(argv[a],"--client=DSHR")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_DIABLOSHR;
        }
        else if (strcmp(argv[a],"-s")==0 || strcmp(argv[a],"--client=STAR")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_STARCRAFT;
        }
        else if (strcmp(argv[a],"--client=SSHR")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_SHAREWARE;
        }
	else if (strcmp(argv[a],"-w")==0 || strcmp(argv[a],"--client=W2BN")==0)
	{
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_WARCIIBNE;
	}
        else if (strcmp(argv[a],"--client=D2DV")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_DIABLO2DV;
        }
        else if (strcmp(argv[a],"--client=D2XP")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_DIABLO2XP;
        }
        else if (strcmp(argv[a],"--client=WAR3")==0)
        {
            if (clienttag)
            {
                fprintf(stderr,"%s: client type was already specified as \"%s\"\n",argv[0],clienttag);
                usage(argv[0]);
            }
            clienttag = CLIENTTAG_WARCRAFT3;
        }
        else if (strncmp(argv[a],"--client=",9)==0)
        {
            fprintf(stderr,"%s: unknown client tag \"%s\"\n",argv[0],&argv[a][9]);
            usage(argv[0]);
        }
	else if (strncmp(argv[a],"--hexdump=",10)==0)
	{
	    if (hexfile)
	    {
		fprintf(stderr,"%s: hexdump file was already specified as \"%s\"\n",argv[0],hexfile);
		usage(argv[0]);
	    }
	    hexfile = &argv[a][10];
	}
        else if (strcmp(argv[a],"--arch=IX86")==0)
        {
            if (archtag)
            {
                fprintf(stderr,"%s: client arch was already specified as \"%s\"\n",argv[0],archtag);
                usage(argv[0]);
            }
            archtag = ARCHTAG_WINX86;
        }
        else if (strcmp(argv[a],"--arch=PMAC")==0)
        {
            if (archtag)
            {
                fprintf(stderr,"%s: client arch was already specified as \"%s\"\n",argv[0],archtag);
                usage(argv[0]);
            }
            archtag = ARCHTAG_MACPPC;
        }
        else if (strcmp(argv[a],"--arch=XMAC")==0)
        {
            if (archtag)
            {
                fprintf(stderr,"%s: client arch was already specified as \"%s\"\n",argv[0],archtag);
                usage(argv[0]);
            }
            archtag = ARCHTAG_OSXPPC;
        }
        else if (strncmp(argv[a],"--arch=",7)==0)
        {
            fprintf(stderr,"%s: unknown arch tag \"%s\"\n",argv[0],&argv[a][9]);
            usage(argv[0]);
        }
	else if (strncmp(argv[a],"--startoffset=",14)==0)
	{
	    if (startoffsetoverride)
	    {
		fprintf(stderr,"%s: startoffset was already specified as %u\n",argv[0],startoffset);
		usage(argv[0]);
	    }
            if (str_to_uint(&argv[a][14],&startoffset)<0)
            {
                fprintf(stderr,"%s: startoffset \"%s\" should be a positive integer\n",argv[0],&argv[a][14]);
                usage(argv[0]);
            }
	    startoffsetoverride = 1;
	}
	else if (strncmp(argv[a],"--exists=",9)==0)
	{
	    if (exist_action!=EXIST_ACTION_UNSPEC)
	    {
		fprintf(stderr,"%s: exists was already specified\n",argv[0]);
		usage(argv[0]);
	    }
	    if (argv[a][9]=='o' || argv[a][9]=='O')
	    	exist_action = EXIST_ACTION_OVERWRITE;
	    else if (argv[a][9]=='a' || argv[a][9]=='A')
	    	exist_action = EXIST_ACTION_ASK;
	    else if (argv[a][9]=='b' || argv[a][9]=='B')
	    	exist_action = EXIST_ACTION_BACKUP;
	    else if (argv[a][9]=='r' || argv[a][9]=='R')
	    	exist_action = EXIST_ACTION_RESUME;
	    else {
		fprintf(stderr,"%s: exists must begin with a,A,o,O,b,B,r or R",argv[0]);
		usage(argv[0]);
	    }
	}
	else if (strncmp(argv[a],"--file=",7)==0)
	{
	    if (reqfile)
	    {
		fprintf(stderr,"%s: file was already specified as \"%s\"\n",argv[0],reqfile);
		usage(argv[0]);
	    }
	    reqfile = &argv[a][7];
	}
	else if (strcmp(argv[a],"-v")==0 || strcmp(argv[a],"--version")==0)
	{
            printf("version "BNETD_VERSION"\n");
            return 0;
	}
	else if (strcmp(argv[a],"-h")==0 || strcmp(argv[a],"--help")==0 || strcmp(argv[a],"--usage")==0)
            usage(argv[0]);
        else if (strcmp(argv[a],"--client")==0 || strcmp(argv[a],"--hexdump")==0)
        {
            fprintf(stderr,"%s: option \"%s\" requires an argument\n",argv[0],argv[a]);
            usage(argv[0]);
        }
	else
	{
	    fprintf(stderr,"%s: unknown option \"%s\"\n",argv[0],argv[a]);
	    usage(argv[0]);
	}
    
    if (servport==0)
        servport = BNETD_SERV_PORT;
    if (!clienttag)
        clienttag = CLIENTTAG_STARCRAFT;
    if (!archtag)
        archtag = ARCHTAG_WINX86;
    if (!servname)
	servname = BNETD_DEFAULT_HOST;
    if (exist_action==EXIST_ACTION_UNSPEC)
	exist_action = EXIST_ACTION_ASK;
    
    if (hexfile)
	if (!(hexstrm = fopen(hexfile,"w")))
	    fprintf(stderr,"%s: could not open file \"%s\" for writing the hexdump (fopen: %s)",argv[0],hexfile,strerror(errno));
	else
	    fprintf(hexstrm,"# dump generated by bnftp version "BNETD_VERSION"\n");
    
    if (psock_init()<0)
    {
        fprintf(stderr,"%s: could not inialialize socket functions\n",argv[0]);
        return STATUS_FAILURE;
    }
    
    if (!(host = gethostbyname(servname)))
    {
	fprintf(stderr,"%s: unknown host \"%s\"\n",argv[0],servname);
	return STATUS_FAILURE;
    }
    
    fd_stdin = fileno(stdin);
    if (tcgetattr(fd_stdin,&in_attr_old)>=0)
    {
        in_attr_new = in_attr_old;
        in_attr_new.c_lflag &= ~(ECHO | ICANON); /* turn off ECHO and ICANON */
	in_attr_new.c_cc[VMIN]  = 1; /* require reads to return at least one byte */
        in_attr_new.c_cc[VTIME] = 0; /* no timeout */
        tcsetattr(fd_stdin,TCSANOW,&in_attr_new);
        changed_in = 1;
    }
    else
    {
	fprintf(stderr,"%s: could not get terminal attributes for stdin\n",argv[0]);
	changed_in = 0;
    }
    
    if (client_get_termsize(fd_stdin,&screen_width,&screen_height)<0)
    {
        fprintf(stderr,"%s: could not determine screen size\n",argv[0]);
        if (changed_in)
            tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
        return STATUS_FAILURE;
    }
    
    if ((sd = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP))<0)
    {
	fprintf(stderr,"%s: could not create socket (psock_socket: %s)\n",argv[0],strerror(psock_errno()));
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	return STATUS_FAILURE;
    }
    
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = PSOCK_AF_INET;
    saddr.sin_port   = htons(servport);
    memcpy(&saddr.sin_addr.s_addr,host->h_addr_list[0],host->h_length);
    if (psock_connect(sd,(struct sockaddr *)&saddr,sizeof(saddr))<0)
    {
	fprintf(stderr,"%s: could not connect to server \"%s\" port %hu (psock_connect: %s)\n",argv[0],servname,servport,strerror(psock_errno()));
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	return STATUS_FAILURE;
    }
    
    printf("Connected to %s:%hu.\n",inet_ntoa(saddr.sin_addr),servport);
    
#ifdef CLIENTDEBUG
    eventlog_set(stderr);
#endif
    
    if (!(packet = packet_create(packet_class_init)))
    {
	fprintf(stderr,"%s: could not create packet\n",argv[0]);
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	return STATUS_FAILURE;
    }
    bn_byte_set(&packet->u.client_initconn.class,CLIENT_INITCONN_CLASS_FILE);
    if (hexstrm)
    {
	fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		sd,
		packet_get_class_str(packet),(unsigned int)packet_get_class(packet),
		packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),
		packet_get_size(packet));
	hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));
    }
    client_blocksend_packet(sd,packet);
    packet_del_ref(packet);
    
    if (!(rpacket = packet_create(packet_class_file)))
    {
	fprintf(stderr,"%s: could not create packet\n",argv[0]);
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	return STATUS_FAILURE;
    }
    
    if (!(fpacket = packet_create(packet_class_raw)))
    {
	fprintf(stderr,"%s: could not create packet\n",argv[0]);
	if (changed_in)
	    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	packet_del_ref(rpacket);
	return STATUS_FAILURE;
    }
    
    if (!reqfile) /* if not specified on the command line then prompt for it */
    {
    	munged = 1;
    	commpos = 0;
    	text[0] = '\0';
	
    	for (;;)
    	{
	    switch (client_get_comm("filename: ",text,sizeof(text),&commpos,1,munged,screen_width))
	    {
	    case -1: /* cancel or error */
	    	printf("\n");
	    	if (changed_in)
		    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	    	packet_del_ref(fpacket);
	    	packet_del_ref(rpacket);
	    	return STATUS_FAILURE;
		
	    case 0: /* timeout */
	    	munged = 0;
	    	continue;
		
	    case 1:
	    	munged = 0;
	    	if (text[0]=='\0')
		    continue;
	    	printf("\n");
	    }
	    break;
    	}
	reqfile = text;
    }
    
    if (stat(reqfile,&exist_buf)==0) /* check if the file exists */
    {
	char text2[MAX_MESSAGE_LEN];
	    
    	munged = 1;
	commpos = 0;
	text2[0] = '\0';
	
  	while (exist_action==EXIST_ACTION_ASK)
	{
	    switch (client_get_comm("File exists [O]verwrite, [B]ackup or [R]esume?: ",text2,sizeof(text2),&commpos,1,munged,screen_width))
	    {
	    case -1: /* cancel or error */
	    	printf("\n");
	    	if (changed_in)
		    tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
	    	packet_del_ref(fpacket);
	    	packet_del_ref(rpacket);
	    	return STATUS_FAILURE;
		
	    case 0: /* timeout */
	    	munged = 0;
	    	continue;
		
	    case 1:
	    	munged = 0;
	    	if (text2[0]=='\0')
		    continue;
	    	printf("\n");
		break;
	    }
	    
	    switch (text2[0])
	    {
	    case 'o':
	    case 'O':
		exist_action = EXIST_ACTION_OVERWRITE;
		break;
	    case 'b':
	    case 'B':
		exist_action = EXIST_ACTION_BACKUP;
		break;
	    case 'r':
	    case 'R':
		exist_action = EXIST_ACTION_RESUME;
		break;
	    default:
		printf("Please answer with o,O,b,B,r or R.\n");
		munged = 1;
		continue;
	    }
	    break;
	}
	
	switch (exist_action)
	{
	case EXIST_ACTION_OVERWRITE:
	    if (!startoffsetoverride)
	    	startoffset = 0;
	    break;
	case EXIST_ACTION_BACKUP:
	    {
		char *       bakfile;
		unsigned int bnr;
		int          renamed=0;
		
		if (!(bakfile = malloc(strlen(reqfile)+1+2+1))) /* assuming we go up to bnr 99 we need reqfile+'.'+'99'+'\0' */
		{
		    fprintf(stderr,"%s: unable to allocate memory for backup filename.\n",argv[0]);
		    if (changed_in)
			tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
		    packet_del_ref(fpacket);
		    packet_del_ref(rpacket);
		    return STATUS_FAILURE;
		}
		
		for (bnr=0; bnr<100; bnr++)
		{
		    sprintf(bakfile,"%s.%d",reqfile,bnr);
		    if (stat(bakfile,&exist_buf)==0)
			continue; /* backup exists */
		    /* backup does not exist */
		    if (rename(reqfile,bakfile)<0) /* just rename the existing file to the backup */
			fprintf(stderr,"%s: could not create backup file \"%s\" (rename: %s)\n",argv[0],bakfile,strerror(errno));
		    else
		    {
			renamed = 1;
			printf("Renaming \"%s\" to \"%s\".\n",reqfile,bakfile);
		    }
		    break;
		}
		free(bakfile);
		if (!renamed)
		{
		    fprintf(stderr,"%s: could not create backup for \"%s\".\n",argv[0],reqfile);
		    if (changed_in)
			tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
		    packet_del_ref(fpacket);
		    packet_del_ref(rpacket);
		    return STATUS_FAILURE;
		}
	    	if (!startoffsetoverride)
	    	    startoffset = 0;
	    }
	    break;
	case EXIST_ACTION_RESUME:
	    if (!startoffsetoverride)
	    	startoffset = exist_buf.st_size;
	    break;	    	
	}	
    }
    else
	if (!startoffsetoverride)
	    startoffset = 0;
    
    if (changed_in)
	tcsetattr(fd_stdin,TCSAFLUSH,&in_attr_old);
    
    if (!(packet = packet_create(packet_class_file)))
    {
	fprintf(stderr,"%s: could not create packet\n",argv[0]);
	packet_del_ref(fpacket);
	packet_del_ref(rpacket);
	return STATUS_FAILURE;
    }
    packet_set_size(packet,sizeof(t_client_file_req));
    packet_set_type(packet,CLIENT_FILE_REQ);
    bn_int_tag_set(&packet->u.client_file_req.archtag,archtag);
    bn_int_tag_set(&packet->u.client_file_req.clienttag,clienttag);
    bn_int_set(&packet->u.client_file_req.adid,0);
    bn_int_set(&packet->u.client_file_req.extensiontag,0);
    bn_int_set(&packet->u.client_file_req.startoffset,startoffset);
    bn_long_set_a_b(&packet->u.client_file_req.timestamp,0x00000000,0x00000000);
    packet_append_string(packet,reqfile);
    if (hexstrm)
    {
	fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		sd,
		packet_get_class_str(packet),(unsigned int)packet_get_class(packet),
		packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),
		packet_get_size(packet));
	hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));
    }
    printf("\nRequesting info...");
    fflush(stdout);
    client_blocksend_packet(sd,packet);
    packet_del_ref(packet);
    
    do
    {
	if (client_blockrecv_packet(sd,rpacket)<0)
	{
	    fprintf(stderr,"%s: server closed connection\n",argv[0]);
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
	if (hexstrm)
	{
	    fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		     sd,
		     packet_get_class_str(rpacket),(unsigned int)packet_get_class(rpacket),
		     packet_get_type_str(rpacket,packet_dir_from_server),packet_get_type(rpacket),
		     packet_get_size(rpacket));
	    hexdump(hexstrm,packet_get_raw_data(rpacket,0),packet_get_size(rpacket));
	}
    }
    while (packet_get_type(rpacket)!=SERVER_FILE_REPLY);
    
    filelen = bn_int_get(rpacket->u.server_file_reply.filelen);
    bn_long_to_bnettime(rpacket->u.server_file_reply.timestamp,&bntime);
    tm = bnettime_to_time(bntime);
    strftime(timestr,FILE_TIME_MAXLEN,FILE_TIME_FORMAT,localtime(&tm));
    filename = packet_get_str_const(rpacket,sizeof(t_server_file_reply),MAX_FILENAME_STR);
    
    if (exist_action==EXIST_ACTION_RESUME)
    {
	if (!(fp = fopen(reqfile,"ab")))
	{
	    fprintf(stderr,"%s: could not open file \"%s\" for appending (fopen: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
    }
    else
    {
	if (!(fp = fopen(reqfile,"wb")))
	{
	    fprintf(stderr,"%s: could not open file \"%s\" for writing (fopen: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
    }
    
    printf("\n name: \"");
    str_print_term(stdout,filename,0,0);
    printf("\"\n changed: %s\n length: %u bytes\n",timestr,filelen);
    fflush(stdout);
    
    if (startoffset>0) {
	filelen -= startoffset; /* for resuming files */
	printf("Resuming at position %u (%u bytes remaining).\n",startoffset,filelen);
    }
    
    printf("\nSaving to \"%s\"...",reqfile);

    for (currsize=0; currsize+MAX_PACKET_SIZE<=filelen; currsize+=MAX_PACKET_SIZE)
    {
	printf(".");
	fflush(stdout);
	
	if (client_blockrecv_raw_packet(sd,fpacket,MAX_PACKET_SIZE)<0)
	{
	    printf("error\n");
	    fprintf(stderr,"%s: server closed connection\n",argv[0]);
	    if (fclose(fp)<0)
		fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
	if (hexstrm)
	{
	    fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		     sd,
		     packet_get_class_str(fpacket),(unsigned int)packet_get_class(fpacket),
		     packet_get_type_str(fpacket,packet_dir_from_server),packet_get_type(fpacket),
		     packet_get_size(fpacket));
	    hexdump(hexstrm,packet_get_raw_data(fpacket,0),packet_get_size(fpacket));
	}
	if (fwrite(packet_get_raw_data_const(fpacket,0),1,MAX_PACKET_SIZE,fp)<MAX_PACKET_SIZE)
	{
	    printf("error\n");
	    fprintf(stderr,"%s: could not write to file \"%s\" (fwrite: %s)\n",argv[0],reqfile,strerror(errno));
	    if (fclose(fp)<0)
		fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
    }
    filelen -= currsize;
    if (filelen)
    {
	printf(".");
	fflush(stdout);
	
	if (client_blockrecv_raw_packet(sd,fpacket,filelen)<0)
	{
	    printf("error\n");
	    fprintf(stderr,"%s: server closed connection\n",argv[0]);
	    if (fclose(fp)<0)
		fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
	if (hexstrm)
	{
	    fprintf(hexstrm,"%d: recv class=%s[0x%02hx] type=%s[0x%04hx] length=%u\n",
		     sd,
		     packet_get_class_str(fpacket),(unsigned int)packet_get_class(fpacket),
		     packet_get_type_str(fpacket,packet_dir_from_server),packet_get_type(fpacket),
		     packet_get_size(fpacket));
	    hexdump(hexstrm,packet_get_raw_data(fpacket,0),packet_get_size(fpacket));
	}
	if (fwrite(packet_get_raw_data_const(fpacket,0),1,filelen,fp)<filelen)
	{
	    printf("error\n");
	    fprintf(stderr,"%s: could not write to file \"%s\"\n",argv[0],reqfile);
	    if (fclose(fp)<0)
		fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	    packet_del_ref(fpacket);
	    packet_del_ref(rpacket);
	    return STATUS_FAILURE;
	}
    }
    
    packet_del_ref(fpacket);
    packet_del_ref(rpacket);
    
    if (hexstrm)
    {
	fprintf(hexstrm,"# end of dump\n");
	if (fclose(hexstrm)<0)
	    fprintf(stderr,"%s: could not close hexdump file \"%s\" after writing (fclose: %s)",argv[0],hexfile,strerror(errno));
    }
    
    if (fclose(fp)<0)
    {
	fprintf(stderr,"%s: could not close file \"%s\" after writing (fclose: %s)\n",argv[0],reqfile,strerror(errno));
	return STATUS_FAILURE;
    }
    
    printf("done\n");
    return STATUS_FAILURE;
}
main(int argc, char *argv[])
{
    unsigned short port;           /* port server binds to                  */
    char buf[32];                  /* buffer for sending and receiving data */
    struct sockaddr_in tcp_client; /* client address information            */
    struct sockaddr_in tcp_server; /* server address information            */
    struct sockaddr_in udp_client;
    struct sockaddr_in udp_server;
    int tcpsock,udpsock;           /* socket for accepting connections      */
    int ns;                        /* socket connected to client            */
    int namelen;                   /* length of client name                 */
    int sockint, client_address_size;
    fd_set rdfds;                  /* read set mask for select() call */
    int width=0;                   /* # bits to be checked for select() call */
    int readysock=0;
    struct timeval timeout;

/*
 * Check arguments. Should be only one: the port number to bind to.
 */

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s port\n", argv[0]);
        exit(1);
    }

/*
 * Initialize with sockets.
 */
    if ((sockint = sock_init()) != 0)
    {
       printf(" INET.SYS probably is not running");
       exit(2);
    }

/*
 * First argument should be the port.
 */
    port = (unsigned short) atoi(argv[1]);

/*
 *
 * TCP SERVER
 *
 * Get a TCP socket for accepting connections.
 */
    if ((tcpsock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        psock_errno("Socket()");
        exit(3);
    }

/*
 * Bind the TCP socket to the server address.
 */
    tcp_server.sin_family = AF_INET;
    tcp_server.sin_port   = htons(port);
    tcp_server.sin_addr.s_addr = INADDR_ANY;

    if (bind(tcpsock, (struct sockaddr *)&tcp_server, sizeof(tcp_server)) < 0)
    {
        psock_errno("Bind()");
        exit(4);
    }

/*
 * Listen for connections. Specify the backlog as 5.
 */
    if (listen(tcpsock, 5) != 0)
    {
        psock_errno("Listen()");
        exit(5);
    }

/*
 *  UDP SERVER
 *
 * Create a UDP socket in the internet domain and use the
 * default protocol (UDP).
 */
   if ((udpsock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
   {
       psock_errno("socket()");
       exit(6);
   }
/*
 *
 * Bind the UDP socket to the server address.
 *
 */
   udp_server.sin_family      = AF_INET;    /* Server is in Internet Domain */
   udp_server.sin_port        = htons(port);
   udp_server.sin_addr.s_addr = INADDR_ANY; /* Server's Internet Address    */

   if (bind(udpsock, (struct sockaddr *)&udp_server, sizeof(udp_server)) < 0)
   {
       psock_errno("bind()");
       exit(7);
   }

   for(;;)
      {
        /*
         *  polling every 10 seconds instead of blocking indefinitely.
         */
        timeout.tv_sec = 10l;
        timeout.tv_usec = 0l;

        /*
         * read set mask is zeroed before use
         */
        FD_ZERO( &rdfds );

        /*
         * add socket discriptor in the read set mask.
         */
        FD_SET( tcpsock, &rdfds );
        if ( tcpsock > width ) width = tcpsock;
        FD_SET( udpsock, &rdfds );
        if ( udpsock > width ) width = udpsock;

        /*
         * width can be FD_SETSIZE, i.e. 2048.
         */
        width++;

        /*
         * Select() returns the number of socket descriptors selected;
         * if it timed out, then returns 0.
         */
        if ((readysock=select(width, &rdfds, (fd_set *)0, (fd_set *)0, &timeout)) == -1)
         {
           psock_errno("Select()");
           exit(8);
         }

        if (readysock > 0)
         {
           /*
            * Check read readiness on the socket.
            */
           if(FD_ISSET(tcpsock,&rdfds))
            {
             /*
              * Accept a connection.
              */
              namelen = sizeof(tcp_client);
              if ((ns = accept(tcpsock, (struct sockaddr *)&tcp_client, &namelen)) == -1)
               {
                  psock_errno("Accept()");
                  exit(9);
               }

             /*
              * Receive the message on the newly connected socket.
              */
              if (recv(ns, buf, sizeof(buf), 0) == -1)
               {
                  psock_errno("Recv()");
                  exit(10);
               }

             /*
              * Send the message back to the client.
              */
              if (send(ns, buf, sizeof(buf), 0) < 0)
               {
                 psock_errno("Send()");
                 exit(11);
               }
              soclose(ns);
              printf("TCP Server received successfully\n");
            }
           if(FD_ISSET(udpsock,&rdfds))
            {
             /*
              * Receive a message on socket udpsock in buf  of maximum size 32
              * from a client.
              */
              client_address_size = sizeof(udp_client);

              if(recvfrom(udpsock, buf, sizeof(buf), 0, (struct sockaddr *) &udp_client,
                          &client_address_size) <0)
               {
                 psock_errno("recvfrom()");
                 exit(12);
               }
             /*
              * Print the message and the name of the client.
              */
              printf("Received message %s from domain %s port %d internet address %s\n",
              buf,
              (udp_client.sin_family == AF_INET?"AF_INET":"UNKNOWN"),
              ntohs(udp_client.sin_port),
              inet_ntoa(udp_client.sin_addr));
           }
         }
      } /* end of for(;;) loop */

}
Exemplo n.º 11
0
static int sd_accept(t_addr const * curr_laddr, t_laddr_info const * laddr_info, int ssocket, int usocket)
{
    char               tempa[32];
    int                csocket;
    struct sockaddr_in caddr;
    psock_t_socklen    caddr_len;
    unsigned int       raddr;
    unsigned short     rport;

    if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))
	strcpy(tempa,"x.x.x.x:x");

    /* accept the connection */
    memset(&caddr,0,sizeof(caddr)); /* not sure if this is needed... modern systems are ok anyway */
    caddr_len = sizeof(caddr);
    if ((csocket = psock_accept(ssocket,(struct sockaddr *)&caddr,&caddr_len))<0)
    {
	/* BSD, POSIX error for aborted connections, SYSV often uses EAGAIN or EPROTO */
	if (
#ifdef PSOCK_EWOULDBLOCK
	    psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ECONNABORTED
	    psock_errno()==PSOCK_ECONNABORTED ||
#endif
#ifdef PSOCK_EPROTO
	    psock_errno()==PSOCK_EPROTO ||
#endif
	    0)
	    eventlog(eventlog_level_error,"sd_accept","client aborted connection on %s (psock_accept: %s)",tempa,strerror(psock_errno()));
	else /* EAGAIN can mean out of resources _or_ connection aborted :( */
	    if (
#ifdef PSOCK_EINTR
		psock_errno()!=PSOCK_EINTR &&
#endif
		1)
		eventlog(eventlog_level_error,"sd_accept","could not accept new connection on %s (psock_accept: %s)",tempa,strerror(psock_errno()));
	return -1;
    }

#ifdef HAVE_POLL
    if (csocket>=BNETD_MAX_SOCKETS) /* This check is a bit too strict (csocket is probably
                                     * greater than the number of connections) but this makes
                                     * life easier later.
                                     */
    {
	eventlog(eventlog_level_error,"sd_accept","csocket is beyond range allowed by BNETD_MAX_SOCKETS for poll() (%d>=%d)",csocket,BNETD_MAX_SOCKETS);
	psock_close(csocket);
	return -1;
    }
#else
# ifdef FD_SETSIZE
    if (csocket>=FD_SETSIZE) /* fd_set size is determined at compile time */
    {
	eventlog(eventlog_level_error,"sd_accept","csocket is beyond range allowed by FD_SETSIZE for select() (%d>=%d)",csocket,FD_SETSIZE);
	psock_close(csocket);
	return -1;
    }
# endif
#endif
    if (ipbanlist_check(inet_ntoa(caddr.sin_addr))!=0)
    {
	eventlog(eventlog_level_info,"sd_accept","[%d] connection from banned address %s denied (closing connection)",csocket,inet_ntoa(caddr.sin_addr));
	psock_close(csocket);
	return -1;
    }

    eventlog(eventlog_level_info,"sd_accept","[%d] accepted connection from %s on %s",csocket,addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port)),tempa);

    if (prefs_get_use_keepalive())
    {
	int val=1;

	if (psock_setsockopt(csocket,PSOCK_SOL_SOCKET,PSOCK_SO_KEEPALIVE,&val,(psock_t_socklen)sizeof(val))<0)
	    eventlog(eventlog_level_error,"sd_accept","[%d] could not set socket option SO_KEEPALIVE (psock_setsockopt: %s)",csocket,strerror(psock_errno()));
	/* not a fatal error */
    }

    {
	struct sockaddr_in rsaddr;
	psock_t_socklen    rlen;

	memset(&rsaddr,0,sizeof(rsaddr)); /* not sure if this is needed... modern systems are ok anyway */
	rlen = sizeof(rsaddr);
	if (psock_getsockname(csocket,(struct sockaddr *)&rsaddr,&rlen)<0)
	{
	    eventlog(eventlog_level_error,"sd_accept","[%d] unable to determine real local port (psock_getsockname: %s)",csocket,strerror(psock_errno()));
	    /* not a fatal error */
	    raddr = addr_get_ip(curr_laddr);
	    rport = addr_get_port(curr_laddr);
	}
	else
	{
	    if (rsaddr.sin_family!=PSOCK_AF_INET)
	    {
		eventlog(eventlog_level_error,"sd_accept","local address returned with bad address family %d",(int)rsaddr.sin_family);
		/* not a fatal error */
		raddr = addr_get_ip(curr_laddr);
		rport = addr_get_port(curr_laddr);
	    }
	    else
	    {
		raddr = ntohl(rsaddr.sin_addr.s_addr);
		rport = ntohs(rsaddr.sin_port);
	    }
	}
    }

    if (psock_ctl(csocket,PSOCK_NONBLOCK)<0)
    {
	eventlog(eventlog_level_error,"sd_accept","[%d] could not set TCP socket to non-blocking mode (closing connection) (psock_ctl: %s)",csocket,strerror(psock_errno()));
	psock_close(csocket);
	return -1;
    }

    {
	t_connection * c;

	if (!(c = conn_create(csocket,usocket,raddr,rport,addr_get_ip(curr_laddr),addr_get_port(curr_laddr),ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port))))
	{
	    eventlog(eventlog_level_error,"sd_accept","[%d] unable to create new connection (closing connection)",csocket);
	    psock_close(csocket);
	    return -1;
	}

	eventlog(eventlog_level_debug,"sd_accept","[%d] client connected to a %s listening address",csocket,laddr_type_get_str(laddr_info->type));
	switch (laddr_info->type)
	{
	case laddr_type_irc:
	    conn_set_class(c,conn_class_irc);
	    conn_set_state(c,conn_state_connected);
	    break;
	case laddr_type_telnet:
	    conn_set_class(c,conn_class_telnet);
	    conn_set_state(c,conn_state_connected);
	    break;
	case laddr_type_bnet:
	default:
	    /* We have to wait for an initial "magic" byte on bnet connections to
             * tell us exactly what connection class we are dealing with.
             */
	    break;
	}
    }

    return 0;
}
Exemplo n.º 12
0
/* FIXME: No it doesn't!  pcAddress is not ever referenced in this
 * function.
 * CreepLord: Fixed much better way (will accept dns hostnames)
 */
int dbs_server_init(void)
{
	int sd;
	struct sockaddr_in sinInterface;
	int val;
	t_addr	* servaddr;
		
	dbs_server_connection_list=list_create();

	if (d2dbs_d2ladder_init()==-1)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"d2ladder_init() failed");
		return -1;
	}

	if (cl_init(DEFAULT_HASHTBL_LEN, DEFAULT_GS_MAX)==-1)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"cl_init() failed");
		return -1;
	}

	if (psock_init()<0)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_init() failed");
		return -1;
	}
	
	sd = psock_socket(PSOCK_PF_INET, PSOCK_SOCK_STREAM, PSOCK_IPPROTO_TCP);
	if (sd==-1)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_socket() failed : %s",strerror(psock_errno()));
		return -1;
	}

	val = 1;
	if (psock_setsockopt(sd, PSOCK_SOL_SOCKET, PSOCK_SO_REUSEADDR, &val, sizeof(val)) < 0)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_setsockopt() failed : %s",strerror(psock_errno()));
	}

        if (!(servaddr=addr_create_str(d2dbs_prefs_get_servaddrs(),INADDR_ANY,DEFAULT_LISTEN_PORT)))
	{
		eventlog(eventlog_level_error,__FUNCTION__,"could not get servaddr");
		return -1;
	}
	
	sinInterface.sin_family = PSOCK_AF_INET;
	sinInterface.sin_addr.s_addr = htonl(addr_get_ip(servaddr));
	sinInterface.sin_port = htons(addr_get_port(servaddr));
	if (psock_bind(sd, (struct sockaddr*)&sinInterface, (psock_t_socklen)sizeof(struct sockaddr_in)) < 0)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_bind() failed : %s",strerror(psock_errno()));
		return -1;
	}
	if (psock_listen(sd, LISTEN_QUEUE) < 0)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_listen() failed : %s",strerror(psock_errno()));
		return -1;
	}
	addr_destroy(servaddr);
	return sd;
}
void main(int argc, char **argv) {
   int listen_sock, udp_sock, socks[2], newsock;
   struct servent *echoprot;
   struct sockaddr_in server, client;
   int rc;
   int asize;

   // Initialize TCP/IP
   if (sock_init() != 0) {
      printf("INET.SYS probably is not running");
      exit(1);
   }

//------ Create the TCP server socket

   // Create a TCP socket to accept incoming connections
   listen_sock = socket(AF_INET, SOCK_STREAM, 0);
   if (listen_sock == -1) {
       psock_errno("tcp socket()");
       exit(1);
   }

   printf("TCP socket assigned is %d\n", listen_sock);

   // Get the port for the echo protocol out of the etc\services file
   echoprot = getservbyname("echo", "tcp");
   if (echoprot == NULL) {
      printf("The echo/tcp protocol is not listed in the etc/services file\n");
      exit(1);
   }

   // Bind the TCP socket to the echo port
   server.sin_family = AF_INET;
   server.sin_port = echoprot->s_port;
   server.sin_addr.s_addr = INADDR_ANY;

   rc = bind(listen_sock, (struct sockaddr *)&server, sizeof(server));
   if (rc == -1) {
       psock_errno("tcp bind()");
       exit(1);
   }

   // Put the socket into listen mode

   rc = listen(listen_sock, SOMAXCONN);
   if (rc == -1) {
       psock_errno("listen()");
       exit(1);
   }

//------ Create the UDP server socket

   // Create a UDP socket to accept incoming data
   udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
   if (udp_sock == -1) {
       psock_errno("udp socket()");
       exit(1);
   }

   printf("UDP socket assigned is %d\n", udp_sock);

   // Get the port for the echo protocol out of the etc\services file
   echoprot = getservbyname("echo", "udp");
   if (echoprot == NULL) {
      printf("The echo/udp protocol is not listed in the etc/services file\n");
      exit(1);
   }

   // Bind the UDP socket to the echo port
   server.sin_family = AF_INET;
   server.sin_port = echoprot->s_port;
   server.sin_addr.s_addr = INADDR_ANY;

   rc = bind(udp_sock, (struct sockaddr *)&server, sizeof(server));
   if (rc == -1) {
       psock_errno("udp bind()");
       exit(1);
   }

//------ Wait for a connection on the TCP socket or a packet on the UDP socket

   while (1) {
      // Setup the socket array for select()
      socks[0] = listen_sock;
      socks[1] = udp_sock;

      // Wait indefinitely
      rc = os2_select(socks, 2, 0, 0, -1);
      if (rc == -1) {
         // If the select was interrupted, just continue
         if (sock_errno() == SOCEINTR)
            continue;
         psock_errno("main() select()");
         exit(1);
      }

      if (socks[0] != -1) {
         // The TCP listen socket has a connection request ready-- accept() it

         asize = sizeof(client);
         newsock = accept(socks[0], (struct sockaddr *)&client, &asize);
         if (newsock == -1) {
            psock_errno("accept()");
            exit(1);
         }

         printf("Received a TCP connection on socket %d from %s port %d\n",
                newsock, inet_ntoa(client.sin_addr), ntohs(client.sin_port));

         // Start a new thread and pass it the socket it should service

         rc = _beginthread(ServiceTCP, 0, STACK_SIZE, (void *)newsock);
         if (rc == -1) {
            printf("_beginthread() failed\n");
            exit(1);
         }
      }

      // If the UDP socket has a packet waiting, service it

      if (socks[1] != -1)
         ServiceUDP(socks[1]);
   }
}
Exemplo n.º 14
0
extern int net_send_packet(int sock, t_packet const * packet, unsigned int * currsize)
{
    unsigned int size;
    int          addlen;
    
    if (!packet)
    {
	eventlog(eventlog_level_error,"net_send_packet","[%d] got NULL packet (closing connection)",sock);
	return -1;
    }
    if (!currsize)
    {
	eventlog(eventlog_level_error,"net_send_packet","[%d] got NULL currsize (closing connection)",sock);
	return -1;
    }
    
    if ((size = packet_get_size(packet))<1)
    {
	eventlog(eventlog_level_error,"net_send_packet","[%d] packet to send is empty (skipping it)",sock);
	*currsize = 0;
	return 1;
    }
    
    addlen = psock_send(sock,
		        packet_get_raw_data_const(packet,*currsize),
		        size-*currsize,
		        0);
    
    if (addlen<0)
    {
	if (
#ifdef PSOCK_EINTR
	    psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
	    psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
	    psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ENOBUFS
	    psock_errno()==PSOCK_ENOBUFS ||
#endif
#ifdef PSOCK_ENOMEM
	    psock_errno()==PSOCK_ENOMEM ||
#endif
	    0)
	    return 0; /* try again later */
	
	eventlog(eventlog_level_error,"net_send_packet","[%d] could not send data (closing connection) (psock_send: %s)",sock,strerror(psock_errno()));
	return -1;
    }
    
    if (addlen==0)
    {
	eventlog(eventlog_level_error,"net_send_packet","[%d] no data sent (closing connection)",sock);
	return -1;
    }
    
    *currsize += addlen;
    
    /* sent all data in this packet? */
    if (size==*currsize)
    {
	*currsize = 0;
	return 1;
    }
    
    return 0;
}
Exemplo n.º 15
0
// syslogdtcp( )
//
//  Entry into syslogdipc.cpp to setup and start UDP listening
//
void syslogdtcp(  )
{
    bool firststart = TRUE;
    int  msgrecv;
    int  seterr;
    int  i;
    char recv_buffer[1024];
    char *ptr_recv_buffer = recv_buffer;

    // setup for running, if error bug out - don't worry about main
    // will timeout waiting for TCPSEM1.
    seterr = setuptcp( );
    if(seterr)
    {
        if(seterr == 1)
        {
            psock_errno( NULL );
            closetcp( );
        }
        if(seterr == 3) printf("DosGetSharedMem failed\n");
    }

    // main working loop **********************
    while(TRUE)
    {
        // Just my play.  Set SEM1 (SYSLOGD is waiting), delay 1 sec
        // (let SYSLOGD reset), and start now FALSE - continue -
        // sleep 1.5 sec for SEM sets or thread will shutdown
        if(firststart)
        {
            DosPostEventSem(hevTCPSEM1); // tell main I am up!!
            DosSleep(1500);
            firststart = FALSE;
        }

        // clear recv_buffer
        for(i = 0; i < 1024; i++) recv_buffer[i] = 0;

        msgrecv = recv(tcpsocket, ptr_recv_buffer, 1024, 0);  // read socket

        // have a message msgrecv > 0 and not blocked
        if(msgrecv > 0 && prgoptions->securemode)
        {
            if(DosRequestMutexSem(mtxMEMMUX, 60000L) != 0)
            {
                printf("SYSLOGTCP: Timeout waiting for MUX\n");
            }
            else
            {
                if(pShareMem->slotstat[pShareMem->index])
                {
                    printf("SYSLOGTCP: Buffer full!!\n");
                    stats.tcpoverflows++;
                }
                else
                {
                    // clear the slot
                    strnset(pShareMem->data[pShareMem->index], '\0 ',
                                     sizeof(pShareMem->data[pShareMem->index]));

                    // write message into slot replace any character < 32 or > 126
                    // with a space RFC 3164 characters must be in this range
                    for(i = 0; i < strlen(recv_buffer); i++)
                    {
                        if(((int)recv_buffer[i] < 32) || ((int)recv_buffer[i] > 126))
                             pShareMem->data[pShareMem->index][i] = ' ';
                        else pShareMem->data[pShareMem->index][i] = recv_buffer[i];
                    }

                    // set flag slot has message
                    pShareMem->slotstat[pShareMem->index] = 1;

                    ++pShareMem->index;  // increment index to next slot
                    ++stats.systcprecvmsg;

                    // ++tcpatcount;

                    // if reached top of buffer reset index to 0 or bottom
                    if(pShareMem->index == (BUFFER_SLOTS)) pShareMem->index = 0;

                    DosPostEventSem(hevIDLESEM); // wakeup MAIN if IDE
                }
                DosReleaseMutexSem(mtxMEMMUX);
            }

        }  // end of msg recv


        // check for shutdown signal from main
        DosQueryEventSem(hevTCPSEM2, &TCPSEM2Ct);
        if(TCPSEM2Ct && !firststart)
        {
            DosResetEventSem(hevTCPSEM1, &TCPSEM1Ct);
            closetcp( );
        }

        // sleep 1 minute if blocked so do not suckup  the CPU
        if(!prgoptions->securemode) DosSleep(60000L);

    }  //$* end working loop

}  //$* end of syslogdtcp
Exemplo n.º 16
0
static int proxy_process(unsigned short server_listen_port, struct sockaddr_in servaddr)
{
    int                lsock;
    struct sockaddr_in laddr;
    t_psock_fd_set     rfds, wfds;
    int                highest_fd;
    int                udpsock;
    t_virtconn *       vc;
    t_elem const *     curr;
    int                csocket;
    int                ssocket;
    
    if ((udpsock = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_DGRAM,PSOCK_IPPROTO_UDP))<0)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create UDP socket (psock_socket: %s)",pstrerror(psock_errno()));
	return -1;
    }
    if (psock_ctl(udpsock,PSOCK_NONBLOCK)<0)
	eventlog(eventlog_level_error,__FUNCTION__,"could not set UDP listen socket to non-blocking mode (psock_ctl: %s)",pstrerror(psock_errno()));
    
    if ((lsock = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP))<0)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create listening socket (psock_socket: %s)",pstrerror(psock_errno()));
        psock_close(udpsock);
	return -1;
    }
    
    {
	int val=1;
	
	if (psock_setsockopt(lsock,PSOCK_SOL_SOCKET,PSOCK_SO_REUSEADDR,&val,(psock_t_socklen)sizeof(int))<0)
	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set socket option SO_REUSEADDR (psock_setsockopt: %s)",lsock,pstrerror(psock_errno()));
	/* not a fatal error... */
    }
    
    memset(&laddr,0,sizeof(laddr));
    laddr.sin_family = PSOCK_AF_INET;
    laddr.sin_port = htons(server_listen_port);
    laddr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (psock_bind(lsock,(struct sockaddr *)&laddr,(psock_t_socklen)sizeof(laddr))<0)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"could not bind socket to address 0.0.0.0:%hu TCP (psock_bind: %s)",server_listen_port,pstrerror(psock_errno()));
        psock_close(udpsock);
	psock_close(lsock);
	return -1;
    }
    
    memset(&laddr,0,sizeof(laddr));
    laddr.sin_family = PSOCK_AF_INET;
    laddr.sin_port = htons(server_listen_port);
    laddr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (psock_bind(udpsock,(struct sockaddr *)&laddr,(psock_t_socklen)sizeof(laddr))<0)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"could not bind socket to address 0.0.0.0:%hu UDP (psock_bind: %s)",server_listen_port,pstrerror(psock_errno()));
	psock_close(udpsock);
	psock_close(lsock);
	return -1;
    }
    eventlog(eventlog_level_info,__FUNCTION__,"bound to UDP port %hu",server_listen_port);
    
    /* tell socket to listen for connections */
    if (psock_listen(lsock,LISTEN_QUEUE)<0)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"could not listen (psock_listen: %s)",pstrerror(psock_errno()));
        psock_close(udpsock);
	psock_close(lsock);
	return -1;
    }
    if (psock_ctl(lsock,PSOCK_NONBLOCK)<0)
	eventlog(eventlog_level_error,__FUNCTION__,"could not set TCP listen socket to non-blocking mode (psock_ctl: %s)",pstrerror(psock_errno()));
    
    eventlog(eventlog_level_info,__FUNCTION__,"listening on TCP port %hu",server_listen_port);
    
    for (;;)
    {
	/* loop over all connections to create the sets for select() */
	PSOCK_FD_ZERO(&rfds);
	PSOCK_FD_ZERO(&wfds);
	highest_fd = lsock;
	PSOCK_FD_SET(lsock,&rfds);
	if (udpsock>highest_fd)
	    highest_fd = udpsock;
	PSOCK_FD_SET(udpsock,&rfds);
	
	LIST_TRAVERSE_CONST(virtconnlist(),curr)
	{
	    vc = elem_get_data(curr);
            csocket = virtconn_get_client_socket(vc);
	    if (queue_get_length((t_queue const * const *)virtconn_get_clientout_queue(vc))>0)
	        PSOCK_FD_SET(csocket,&wfds); /* pending output, also check for writeability */
	    PSOCK_FD_SET(csocket,&rfds);
            
	    if (csocket>highest_fd)
                highest_fd = csocket;
	    
	    switch (virtconn_get_state(vc))
	    {
	    case virtconn_state_connecting:
		eventlog(eventlog_level_debug,__FUNCTION__,"waiting for %d to finish connecting",ssocket);
		ssocket = virtconn_get_server_socket(vc);
		PSOCK_FD_SET(ssocket,&wfds); /* wait for connect to complete */
		
		if (ssocket>highest_fd)
		    highest_fd = ssocket;
		break;
	    case virtconn_state_connected:
		eventlog(eventlog_level_debug,__FUNCTION__,"checking for reading on connected socket %d",ssocket);
		ssocket = virtconn_get_server_socket(vc);
		if (queue_get_length((t_queue const * const *)virtconn_get_serverout_queue(vc))>0)
		    PSOCK_FD_SET(ssocket,&wfds); /* pending output, also check for writeability */
		PSOCK_FD_SET(ssocket,&rfds);
		
		if (ssocket>highest_fd)
		    highest_fd = ssocket;
		break;
	    default: /* avoid warning */
		break;
	    }
	}
	
	/* find which sockets need servicing */
	if (psock_select(highest_fd+1,&rfds,&wfds,NULL,NULL)<0)
	{
	    if (errno!=PSOCK_EINTR)
	        eventlog(eventlog_level_error,__FUNCTION__,"select failed (select: %s)",pstrerror(errno));
	    continue;
	}
	
	/* check for incoming connection */
	if (PSOCK_FD_ISSET(lsock,&rfds))
	{
            int                asock;
	    struct sockaddr_in caddr;
	    psock_t_socklen    caddr_len;
            
	    /* accept the connection */
	    caddr_len = sizeof(caddr);
	    if ((asock = psock_accept(lsock,(struct sockaddr *)&caddr,&caddr_len))<0)
	    {
		if (psock_errno()==PSOCK_EWOULDBLOCK || psock_errno()==PSOCK_ECONNABORTED) /* BSD, POSIX error for aborted connections, SYSV often uses EAGAIN */
		    eventlog(eventlog_level_error,__FUNCTION__,"client aborted connection (psock_accept: %s)",pstrerror(psock_errno()));
		else /* EAGAIN can mean out of resources _or_ connection aborted */
		    if (psock_errno()!=PSOCK_EINTR)
			eventlog(eventlog_level_error,__FUNCTION__,"could not accept new connection (psock_accept: %s)",pstrerror(psock_errno()));
	    }
	    else
	    {
		int ssd;
		int val=1;
		
		eventlog(eventlog_level_info,__FUNCTION__,"[%d] accepted connection from %s:%hu",asock,inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));
		
		if (psock_setsockopt(asock,PSOCK_SOL_SOCKET,PSOCK_SO_KEEPALIVE,&val,(psock_t_socklen)sizeof(val))<0)
		    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set socket option SO_KEEPALIVE (psock_setsockopt: %s)",asock,pstrerror(psock_errno()));
		    /* not a fatal error */
		
		if (psock_ctl(asock,PSOCK_NONBLOCK)<0)
		{
		    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set TCP socket to non-blocking mode (closing connection) (psock_ctl: %s)",asock,pstrerror(psock_errno()));
		    psock_close(asock);
		}
		else
		    if ((ssd = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP))<0)
		    {
			eventlog(eventlog_level_error,__FUNCTION__,"[%d] could create TCP socket (closing connection) (psock_socket: %s)",asock,pstrerror(psock_errno()));
			psock_close(asock);
		    }
		    else
			if (psock_ctl(ssd,PSOCK_NONBLOCK)<0)
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set TCP socket to non-blocking mode (closing connection) (psock_ctl: %s)",asock,pstrerror(psock_errno()));
			    psock_close(ssd);
			    psock_close(asock);
			}
			else
			    if (!(vc = virtconn_create(asock,ssd,ntohl(caddr.sin_addr.s_addr),BNETD_MIN_TEST_PORT)))
			    {
				eventlog(eventlog_level_error,__FUNCTION__,"[%d] unable to create new connection (closing connection)",asock);
				psock_close(ssd);
				psock_close(asock);
			    }
			    else
			    {
				memset(&caddr,0,sizeof(caddr));
				caddr.sin_family = PSOCK_AF_INET;
				caddr.sin_port = htons(virtconn_get_udpport(vc));
				caddr.sin_addr.s_addr = htonl(virtconn_get_udpaddr(vc));
				eventlog(eventlog_level_info,__FUNCTION__,"[%d] addr now %s:%hu",asock,inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));
			    }
	    }
	}
	
	eventlog(eventlog_level_debug,__FUNCTION__,"checking for incoming UDP");
	if (PSOCK_FD_ISSET(udpsock,&rfds))
	{
	    t_packet *         upacket;
	    struct sockaddr_in toaddr;
	    struct sockaddr_in fromaddr;
	    psock_t_socklen    fromlen;
	    int                len;
	    
	    if (!(upacket = packet_create(packet_class_raw)))
		eventlog(eventlog_level_error,__FUNCTION__,"could not allocate raw packet for input");
	    else
	    {
		/* packet_set_flags(upacket,PROXY_FLAG_UDP);*/
		
		fromlen = sizeof(fromaddr);
		if ((len = psock_recvfrom(udpsock,packet_get_raw_data_build(upacket,0),MAX_PACKET_SIZE,0,(struct sockaddr *)&fromaddr,&fromlen))<0)
		{
		    if (psock_errno()!=PSOCK_EINTR && psock_errno()!=PSOCK_EAGAIN && psock_errno()!=PSOCK_EWOULDBLOCK)
			eventlog(eventlog_level_error,__FUNCTION__,"could not recv UDP datagram (psock_recvfrom: %s)",pstrerror(psock_errno()));
		}
		else
		{
		    if (fromaddr.sin_family!=PSOCK_AF_INET)
			eventlog(eventlog_level_error,__FUNCTION__,"got UDP datagram with bad address family %d",fromaddr.sin_family);
		    else
		    {
			char tempa[32];
			char tempb[32];
			
			packet_set_size(upacket,len);
			
			if (fromaddr.sin_addr.s_addr==servaddr.sin_addr.s_addr) /* from server */
			{
			    if ((curr = list_get_first_const(virtconnlist()))) /* hack.. find proper client */
			    {
				vc = elem_get_data(curr);
				memset(&toaddr,0,sizeof(toaddr));
				toaddr.sin_family = PSOCK_AF_INET;
				toaddr.sin_port = htons(virtconn_get_udpport(vc));
				toaddr.sin_addr.s_addr = htonl(virtconn_get_udpaddr(vc));
				eventlog(eventlog_level_info,__FUNCTION__,"[%d] addr by UDP send is %s:%hu",virtconn_get_client_socket(vc),inet_ntoa(toaddr.sin_addr),ntohs(toaddr.sin_port));
				
				if (hexstrm)
				{
				    strcpy(tempa,inet_ntoa(fromaddr.sin_addr));
				    strcpy(tempb,inet_ntoa(toaddr.sin_addr));
				    fprintf(hexstrm,"%d: srv prot=UDP from=%s:%hu to=%s:%hu length=%d\n",
					    udpsock,
					    tempa,
					    ntohs(fromaddr.sin_port),
					    tempb,
					    ntohs(toaddr.sin_port),
					    len);
				    hexdump(hexstrm,packet_get_raw_data(upacket,0),len);
				}
				
				/*queue_push_packet(virtconn_get_clientout_queue(__));*/ /* where to queue ... */
				for (;;) /* hack.. just block for now */
				{
				    if (psock_sendto(udpsock,packet_get_raw_data_const(upacket,0),len,0,
					             (struct sockaddr *)&toaddr,(psock_t_socklen)sizeof(toaddr))<len)
				    {
					if (psock_errno()==PSOCK_EINTR || psock_errno()==PSOCK_EAGAIN || psock_errno()==PSOCK_EWOULDBLOCK)
					    continue;
					eventlog(eventlog_level_error,__FUNCTION__,"could not send UDP datagram to client (psock_sendto: %s)",pstrerror(psock_errno()));
				    }
				    break;
				}
			    }
			}
			else /* from client */
			{
			    if (hexstrm)
			    {
				strcpy(tempa,inet_ntoa(fromaddr.sin_addr));
				strcpy(tempb,inet_ntoa(servaddr.sin_addr));
				
				fprintf(hexstrm,"%d: clt prot=UDP from=%s:%hu to=%s:%hu length=%d\n",
					udpsock,
					tempa,
					ntohs(fromaddr.sin_port),
					tempb,
					ntohs(servaddr.sin_port),
					len);
				hexdump(hexstrm,packet_get_raw_data(upacket,0),len);
			    }
			    /*queue_push_packet(virtconn_get_serverout_queue(vc));*/
			    for (;;) /* hack.. just block for now */
			    {
				if (psock_sendto(udpsock,packet_get_raw_data_const(upacket,0),len,0,
					         (struct sockaddr *)&servaddr,(psock_t_socklen)sizeof(servaddr))<len)
				{
				    if (psock_errno()==PSOCK_EINTR || psock_errno()==PSOCK_EAGAIN || psock_errno()==PSOCK_EWOULDBLOCK)
					continue;
				    eventlog(eventlog_level_error,__FUNCTION__,"could not send UDP datagram to server (psock_sendto: %s)",pstrerror(psock_errno()));
				}
				break;
			    }
			}
		    }
		}
		packet_del_ref(upacket);
	    }
	}
	
	/* search connections for sockets that need service */
	eventlog(eventlog_level_debug,__FUNCTION__,"checking for sockets that need service");
	LIST_TRAVERSE_CONST(virtconnlist(),curr)
	{
	    unsigned int currsize;
	    t_packet *   packet;
	    
	    vc = elem_get_data(curr);
	    
            csocket = virtconn_get_client_socket(vc);
	    if (virtconn_get_state(vc)==virtconn_state_connected ||
		virtconn_get_state(vc)==virtconn_state_connecting)
		ssocket = virtconn_get_server_socket(vc);
	    else
		ssocket = -1;
	    
	    eventlog(eventlog_level_debug,__FUNCTION__,"checking %d for client readability",csocket);
	    if (PSOCK_FD_ISSET(csocket,&rfds))
	    {
		if (virtconn_get_state(vc)==virtconn_state_initial)
		{
		    if (init_virtconn(vc,servaddr)<0)
		    {
			virtconn_destroy(vc);
			continue;
		    }
		}
		else
		{
		    currsize = virtconn_get_clientin_size(vc);
		    
		    if (!queue_get_length(virtconn_get_clientin_queue(vc)))
		    {
			switch (virtconn_get_class(vc))
			{
			case virtconn_class_bnet:
			    if (!(packet = packet_create(packet_class_bnet)))
			    {
				eventlog(eventlog_level_error,__FUNCTION__,"could not allocate normal packet for input");
				continue;
			    }
			    break;
			case virtconn_class_file:
			    if (!(packet = packet_create(packet_class_file)))
			    {
				eventlog(eventlog_level_error,__FUNCTION__,"could not allocate file packet for input");
				continue;
			    }
			    break;
			case virtconn_class_bot:
			    if (!(packet = packet_create(packet_class_raw)))
			    {
				eventlog(eventlog_level_error,__FUNCTION__,"could not allocate raw packet for input");
				continue;
			    }
			    packet_set_size(packet,1); /* start by only reading one char */
			    break;
			default:
			    eventlog(eventlog_level_error,__FUNCTION__,"[%d] connection has bad type (closing connection)",virtconn_get_client_socket(vc));
			    virtconn_destroy(vc);
			    continue;
			}
			queue_push_packet(virtconn_get_clientin_queue(vc),packet);
			packet_del_ref(packet);
			if (!queue_get_length(virtconn_get_clientin_queue(vc)))
			    continue; /* push failed */
			currsize = 0;
		    }
		    
		    packet = queue_peek_packet((t_queue const * const *)virtconn_get_clientin_queue(vc)); /* avoid warning */
		    switch (net_recv_packet(csocket,packet,&currsize))
		    {
		    case -1:
			virtconn_destroy(vc);
			continue;
			
		    case 0: /* still working on it */
			virtconn_set_clientin_size(vc,currsize);
			break;
			
		    case 1: /* done reading */
			if (virtconn_get_class(vc)==virtconn_class_bot &&
			    currsize<MAX_PACKET_SIZE)
			{
			    char const * const temp=packet_get_raw_data_const(packet,0);
			    
			    if (temp[currsize-1]!='\r' && temp[currsize-1]!='\n')
			    {
				virtconn_set_clientin_size(vc,currsize);
				packet_set_size(packet,currsize+1);
			        break; /* no end of line, get another char */
			    }
			    /* got a complete line... fall through */
			}
			
			packet = queue_pull_packet(virtconn_get_clientin_queue(vc));
			
			if (hexstrm)
			{
			    fprintf(hexstrm,"%d: cli class=%s[0x%04hx] type=%s[0x%04hx] length=%hu\n",
				    csocket,
				    packet_get_class_str(packet),packet_get_class(packet),
				    packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),
				    packet_get_size(packet));
			    hexdump(hexstrm,packet_get_raw_data_const(packet,0),packet_get_size(packet));
			}
			
			queue_push_packet(virtconn_get_serverout_queue(vc),packet);
			packet_del_ref(packet);
			virtconn_set_clientin_size(vc,0);
		    }
		}
	    }
	    
	    eventlog(eventlog_level_debug,__FUNCTION__,"checking %d for server readability",ssocket);
	    if (ssocket!=-1 && PSOCK_FD_ISSET(ssocket,&rfds))
	    {
		currsize = virtconn_get_serverin_size(vc);
		
		if (!queue_get_length(virtconn_get_serverin_queue(vc)))
		{
		    switch (virtconn_get_class(vc))
		    {
		    case virtconn_class_bnet:
			if (!(packet = packet_create(packet_class_bnet)))
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"could not allocate normal packet for input");
			    continue;
			}
			break;
		    case virtconn_class_file:
			{
			    unsigned int fileleft;
			    
			    if ((fileleft = virtconn_get_fileleft(vc))>0)
			    {
				if (!(packet = packet_create(packet_class_raw)))
				{
				    eventlog(eventlog_level_error,__FUNCTION__,"could not allocate raw file packet for input");
				    continue;
				}
				if (fileleft>MAX_PACKET_SIZE)
				    packet_set_size(packet,MAX_PACKET_SIZE);
				else
				    packet_set_size(packet,fileleft);
			    }
			    else
			    {
				if (!(packet = packet_create(packet_class_file)))
				{
				    eventlog(eventlog_level_error,__FUNCTION__,"could not allocate file packet for input");
				    continue;
				}
			    }
			}
			break;
		    case virtconn_class_bot:
			if (!(packet = packet_create(packet_class_raw)))
			{
			    eventlog(eventlog_level_error,__FUNCTION__,"could not allocate raw packet for input");
			    continue;
			}
			packet_set_size(packet,MAX_PACKET_SIZE); /* read as much as possible */
			break;
		    default:
			eventlog(eventlog_level_error,__FUNCTION__,"[%d] connection has bad type (closing connection)",virtconn_get_client_socket(vc));
			virtconn_destroy(vc);
			continue;
		    }
		    queue_push_packet(virtconn_get_serverin_queue(vc),packet);
		    packet_del_ref(packet);
		    if (!queue_get_length(virtconn_get_serverin_queue(vc)))
			continue; /* push failed */
		    currsize = 0;
		}
		
		packet = queue_peek_packet((t_queue const * const *)virtconn_get_serverin_queue(vc)); /* avoid warning */
		switch (net_recv_packet(ssocket,packet,&currsize))
		{
		case -1:
		    virtconn_destroy(vc);
		    continue;
		    
		case 0: /* still working on it */
		    virtconn_set_serverin_size(vc,currsize);
		    if (virtconn_get_class(vc)!=virtconn_class_bot || currsize<1)
			break;
		    else
			packet_set_size(packet,currsize);
		    /* fallthough... we take what we can get with the bot data */
		    
		case 1: /* done reading */
		    packet = queue_pull_packet(virtconn_get_serverin_queue(vc));
		    if (virtconn_get_class(vc)==virtconn_class_file)
		    {
			unsigned int len=virtconn_get_fileleft(vc);
			
			if (len)
			    virtconn_set_fileleft(vc,len-currsize);
			else if (packet_get_type(packet)==SERVER_FILE_REPLY &&
				 packet_get_size(packet)>=sizeof(t_server_file_reply))
			    virtconn_set_fileleft(vc,bn_int_get(packet->u.server_file_reply.filelen));
		    }
		    queue_push_packet(virtconn_get_clientout_queue(vc),packet);
		    packet_del_ref(packet);
		    virtconn_set_serverin_size(vc,0);
		}
	    }
	    
	    eventlog(eventlog_level_debug,__FUNCTION__,"checking %d for client writeability",csocket);
	    if (PSOCK_FD_ISSET(csocket,&wfds))
	    {
		currsize = virtconn_get_clientout_size(vc);
		switch (net_send_packet(csocket,queue_peek_packet((t_queue const * const *)virtconn_get_clientout_queue(vc)),&currsize)) /* avoid warning */
		{
		case -1:
		    virtconn_destroy(vc);
		    continue;
		    
		case 0: /* still working on it */
		    virtconn_set_clientout_size(vc,currsize);
		    break;
		    
		case 1: /* done sending */
		    packet = queue_pull_packet(virtconn_get_clientout_queue(vc));
		    
		    if (hexstrm)
		    {
			fprintf(hexstrm,"%d: srv class=%s[0x%04hx] type=%s[0x%04hx] length=%hu\n",
				csocket,
				packet_get_class_str(packet),packet_get_class(packet),
				packet_get_type_str(packet,packet_dir_from_server),packet_get_type(packet),
				packet_get_size(packet));
			hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));
		    }
		    
		    packet_del_ref(packet);
		    virtconn_set_clientout_size(vc,0);
		}
	    }
	    
	    eventlog(eventlog_level_debug,__FUNCTION__,"checking %d for server writeability",ssocket);
	    if (ssocket!=-1 && PSOCK_FD_ISSET(ssocket,&wfds))
	    {
		if (virtconn_get_state(vc)==virtconn_state_connecting)
		{
		    int             err;
		    psock_t_socklen errlen;
		    
		    err = 0;
		    errlen = sizeof(err);
		    if (psock_getsockopt(ssocket,PSOCK_SOL_SOCKET,PSOCK_SO_ERROR,&err,&errlen)<0)
		    {
			eventlog(eventlog_level_error,__FUNCTION__,"[%d] unable to read socket error (psock_getsockopt[psock_connect]: %s)",virtconn_get_client_socket(vc),pstrerror(psock_errno()));
			virtconn_destroy(vc);
			continue;
		    }
		    if (errlen==0 || err==0)
			virtconn_set_state(vc,virtconn_state_connected);
		    else
		    {
			eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not connect to server (psock_getsockopt[psock_connect]: %s)",virtconn_get_client_socket(vc),pstrerror(err));
			virtconn_destroy(vc);
			continue;
		    }
		}
		else
		{
		    currsize = virtconn_get_serverout_size(vc);
		    switch (net_send_packet(ssocket,queue_peek_packet((t_queue const * const *)virtconn_get_serverout_queue(vc)),&currsize)) /* avoid warning */
		    {
		    case -1:
			virtconn_destroy(vc);
			continue;
			
		    case 0: /* still working on it */
			virtconn_set_serverout_size(vc,currsize);
			break;
			
		    case 1: /* done sending */
			packet = queue_pull_packet(virtconn_get_serverout_queue(vc));
			packet_del_ref(packet);
			virtconn_set_serverout_size(vc,0);
		    }
		}
	    }
	}
Exemplo n.º 17
0
static int init_virtconn(t_virtconn * vc, struct sockaddr_in servaddr)
{
    int  addlen;
    char connect_type;
    
    /* determine connection type by first character sent by client */
    addlen = psock_recv(virtconn_get_client_socket(vc),&connect_type,sizeof(char),0);
    
    if (addlen<0 && (psock_errno()==PSOCK_EINTR || psock_errno()==PSOCK_EAGAIN || psock_errno()==PSOCK_EWOULDBLOCK))
	return 0;
    
    /* error occurred or connection lost */
    if (addlen<1)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not get virtconn class (closing connection) (psock_recv: %s)",virtconn_get_client_socket(vc),pstrerror(psock_errno()));
	return -1;
    }
    
    switch (connect_type)
    {
    case CLIENT_INITCONN_CLASS_BNET:
	eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated normal connection",virtconn_get_client_socket(vc));
	virtconn_set_class(vc,virtconn_class_bnet);
	
	break;
	
    case CLIENT_INITCONN_CLASS_FILE:
	eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated file download connection",virtconn_get_client_socket(vc));
	virtconn_set_class(vc,virtconn_class_file);
	
	break;
	
    case CLIENT_INITCONN_CLASS_BOT:
	eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated chat bot connection",virtconn_get_client_socket(vc));
	virtconn_set_class(vc,virtconn_class_bot);
	
	break;
	
    default:
	eventlog(eventlog_level_error,__FUNCTION__,"[%d] client initiated unknown connection type 0x%02hx (length %d) (closing connection)",virtconn_get_client_socket(vc),(unsigned short)connect_type,addlen);
	return -1;
    }
    
    /* now connect to the real server */
    if (psock_connect(virtconn_get_server_socket(vc),(struct sockaddr *)&servaddr,(psock_t_socklen)sizeof(servaddr))<0)
    {
	if (psock_errno()!=PSOCK_EINPROGRESS)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not connect to server (psock_connect: %s)\n",virtconn_get_client_socket(vc),pstrerror(psock_errno()));
	    return -1;
	}
	virtconn_set_state(vc,virtconn_state_connecting);
    }
    else
	virtconn_set_state(vc,virtconn_state_connected);
    
    {
	t_packet * packet;
	
	if (!(packet = packet_create(packet_class_raw)))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create packet",virtconn_get_client_socket(vc));
	    return -1;
	}
	packet_append_data(packet,&connect_type,1);
	queue_push_packet(virtconn_get_serverout_queue(vc),packet);
	packet_del_ref(packet);
    }
    
    return 0;
}
Exemplo n.º 18
0
extern int server_process(void)
{
    t_addrlist *    laddrs;
    t_addr *        curr_laddr;
    t_addr_data     laddr_data;
    t_laddr_info *  laddr_info;
#ifdef HAVE_POLL
    struct pollfd * fds = NULL;
    int             num_fd;
#else
    struct timeval  tv;
    t_psock_fd_set  rfds, wfds;
    int             highest_fd;
#endif
    time_t          curr_exittime, prev_exittime, prev_savetime, track_time, now;
    unsigned int    syncdelta;
    t_connection *  c;
    t_elem const *  acurr;
    t_elem const *  ccurr;
    int             csocket;
#ifdef DO_POSIXSIG
    sigset_t        block_set;
    sigset_t        save_set;
#endif
    unsigned int    count;

    if (psock_init()<0)
    {
	eventlog(eventlog_level_error,"server_process","could not initialize socket functions");
	return -1;
    }

    server_set_name();

    /* Start with the Battle.net address list */
    if (!(laddrs = addrlist_create(prefs_get_bnetdserv_addrs(),INADDR_ANY,BNETD_SERV_PORT)))
    {
	eventlog(eventlog_level_error,"server_process","could not create %s server address list from \"%s\"",laddr_type_get_str(laddr_type_bnet),prefs_get_bnetdserv_addrs());
        if (psock_deinit()<0)
	    eventlog(eventlog_level_error,"server_process","could not deinitialize socket functions");
	return -1;
    }
    /* Mark all these laddrs for being classic Battle.net service */
    LIST_TRAVERSE_CONST(laddrs,acurr)
    {
	curr_laddr = elem_get_data(acurr);
	if (addr_get_data(curr_laddr).p)
	    continue;
	if (!(laddr_info = malloc(sizeof(t_laddr_info))))
	{
	    eventlog(eventlog_level_error,"server_process","could not create %s address info (malloc: %s)",laddr_type_get_str(laddr_type_bnet),strerror(psock_errno()));
	    goto error_addr_list;
	}
        laddr_info->usocket = -1;
        laddr_info->ssocket = -1;
        laddr_info->type = laddr_type_bnet;
	laddr_data.p = laddr_info;
        if (addr_set_data(curr_laddr,laddr_data)<0)
	{
	    eventlog(eventlog_level_error,"server_process","could not set address data");
	    if (laddr_info->usocket!=-1)
	    {
		psock_close(laddr_info->usocket);
		laddr_info->usocket = -1;
	    }
	    if (laddr_info->ssocket!=-1)
	    {
		psock_close(laddr_info->ssocket);
		laddr_info->ssocket = -1;
	    }
	    goto error_poll;
	}
    }
Exemplo n.º 19
0
static int sd_udpinput(t_addr *const curr_laddr, const t_laddr_info *laddr_info,
		       int ssocket, int usocket)
{
  int             err;
  psock_t_socklen errlen;
  t_packet *      upacket;

  if (laddr_info == NULL) {
    (void)ssocket;
  }
  err = 0;
  errlen = sizeof(err);
  if (psock_getsockopt(usocket,PSOCK_SOL_SOCKET,PSOCK_SO_ERROR,&err,&errlen)<0)
  {
    eventlog(eventlog_level_error,"sd_udpinput","[%d] unable to read socket error (psock_getsockopt: %s)",usocket,strerror(psock_errno()));
    return -1;
  }
  if (errlen && err) /* if it was an error, there is no packet to read */
  {
    eventlog(eventlog_level_error,"sd_udpinput","[%d] async UDP socket error notification (psock_getsockopt: %s)",usocket,strerror(err));
    return -1;
  }
  if (!(upacket = packet_create(packet_class_udp)))
  {
    eventlog(eventlog_level_error,"sd_udpinput","could not allocate raw packet for input");
    return -1;
  }

  {
    struct sockaddr_in fromaddr;
    psock_t_socklen    fromlen;
    int                len;

    fromlen = sizeof(fromaddr);
    if ((len = psock_recvfrom(usocket,packet_get_raw_data_build(upacket,0),MAX_PACKET_SIZE,0,(struct sockaddr *)&fromaddr,&fromlen))<0)
    {
      if (
#ifdef PSOCK_EINTR
	  psock_errno()!=PSOCK_EINTR &&
#endif
#ifdef PSOCK_EAGAIN
	  psock_errno()!=PSOCK_EAGAIN &&
#endif
#ifdef PSOCK_EWOULDBLOCK
	  psock_errno()!=PSOCK_EWOULDBLOCK &&
#endif
	  1)
	eventlog(eventlog_level_error,"sd_udpinput","could not recv UDP datagram (psock_recvfrom: %s)",strerror(psock_errno()));
      packet_del_ref(upacket);
      return -1;
    }

    if (fromaddr.sin_family!=PSOCK_AF_INET)
    {
      eventlog(eventlog_level_error,"sd_udpinput","got UDP datagram with bad address family %d",(int)fromaddr.sin_family);
      packet_del_ref(upacket);
      return -1;
    }

    packet_set_size(upacket,len);

    if (hexstrm)
    {
      char tempa[32];

      if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))
	strcpy(tempa,"x.x.x.x:x");
      fprintf(hexstrm,"%d: recv class=%s[0x%02x] type=%s[0x%04x] from=%s to=%s length=%u\n",
	      usocket,
	      packet_get_class_str(upacket),(unsigned int)packet_get_class(upacket),
	      packet_get_type_str(upacket,packet_dir_from_client),packet_get_type(upacket),
	      addr_num_to_addr_str(ntohl(fromaddr.sin_addr.s_addr),ntohs(fromaddr.sin_port)),
	      tempa,
	      packet_get_size(upacket));
      hexdump(hexstrm,packet_get_raw_data(upacket,0),packet_get_size(upacket));
    }

    handle_udp_packet(usocket,ntohl(fromaddr.sin_addr.s_addr),ntohs(fromaddr.sin_port),upacket);
    packet_del_ref(upacket);
  }

  return 0;
}
Exemplo n.º 20
0
extern int main(int argc, char * argv[])
{
    int sockfd;
    
    if (argc<1 || !argv || !argv[0])
    {
        fprintf(stderr,"bad arguments\n");
        return STATUS_FAILURE;
    }
    
    getprefs(argc,argv);
    
    if (!prefs.debug)
        eventlog_del_level("debug");
    if (prefs.logfile)
    {
	eventlog_set(stderr);
        if (eventlog_open(prefs.logfile)<0)
	{
            eventlog(eventlog_level_fatal,__FUNCTION__,"could not use file \"%s\" for the eventlog (exiting)",prefs.logfile);
	    return STATUS_FAILURE;
	}
    }
    
#ifdef DO_DAEMONIZE
    if (!prefs.foreground)
    {
	switch (fork())
	{
	case -1:
	    eventlog(eventlog_level_error,__FUNCTION__,"could not fork (fork: %s)\n",pstrerror(errno));
	    return STATUS_FAILURE;
	case 0: /* child */
	    break;
	default: /* parent */
	    return STATUS_SUCCESS;
	}
	
	close(STDINFD);
	close(STDOUTFD);
	close(STDERRFD);
	
# ifdef HAVE_SETPGID
	if (setpgid(0,0)<0)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgid: %s)\n",pstrerror(errno));
	    return STATUS_FAILURE;
	}
# else
#  ifdef HAVE_SETPGRP
#   ifdef SETPGRP_VOID
	if (setpgrp()<0)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)\n",pstrerror(errno));
	    return STATUS_FAILURE;
	}
#   else
	if (setpgrp(0,0)<0)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)\n",pstrerror(errno));
	    return STATUS_FAILURE;
	}
#   endif
#  else
#   ifdef HAVE_SETSID
	if (setsid()<0)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setsid: %s)\n",pstrerror(errno));
	    return STATUS_FAILURE;
	}
#   else
#    error "One of setpgid(), setpgrp(), or setsid() is required"
#   endif
#  endif
# endif
    }
#endif
    
    if (prefs.pidfile)
    {
#ifdef HAVE_GETPID
        FILE * fp;

        if (!(fp = fopen(prefs.pidfile,"w")))
        {
            eventlog(eventlog_level_error,__FUNCTION__,"unable to open pid file \"%s\" for writing (fopen: %s)",prefs.pidfile,pstrerror(errno));
            prefs.pidfile = NULL;
        }
        else
        {
            fprintf(fp,"%u",(unsigned int)getpid());
            if (fclose(fp)<0)
                eventlog(eventlog_level_error,__FUNCTION__,"could not close pid file \"%s\" after writing (fclose: %s)",prefs.pidfile,pstrerror(errno));
        }
#else
        eventlog(eventlog_level_warn,__FUNCTION__,"no getpid() system call, do not use the -P or the --pidfile option");
        prefs.pidfile = NULL;
#endif
    }
    
#ifdef HAVE_GETPID
    eventlog(eventlog_level_info,__FUNCTION__,"bntrackd version "PVPGN_VERSION" process %u",(unsigned int)getpid());
#else
    eventlog(eventlog_level_info,__FUNCTION__,"bntrackd version "PVPGN_VERSION);
#endif
    
    if (psock_init()<0)
    {
        eventlog(eventlog_level_error,__FUNCTION__,"could not initialize socket functions");
        return STATUS_FAILURE;
    }
    
    /* create the socket */
    if ((sockfd = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_DGRAM,PSOCK_IPPROTO_UDP))<0)
    {
	eventlog(eventlog_level_error,__FUNCTION__,"could not create UDP listen socket (psock_socket: %s)\n",pstrerror(psock_errno()));
	return STATUS_FAILURE;
    }
    
    {
	struct sockaddr_in servaddr;
	
	/* bind the socket to correct port and interface */
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = PSOCK_AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(prefs.port);
	if (psock_bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0)
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"could not bind to UDP port %hu (psock_bind: %s)\n",prefs.port,pstrerror(psock_errno()));
	    return STATUS_FAILURE;
	}
    }
    
    if (server_process(sockfd)<0)
	return STATUS_FAILURE;
    return STATUS_SUCCESS;
}
Exemplo n.º 21
0
extern t_connection * s2s_create(char const * server, unsigned short def_port, t_conn_class cclass)
{
	struct sockaddr_in	addr, laddr;
	psock_t_socklen		laddr_len;
	unsigned int		ip;
	unsigned short		port;
	int			sock, connected;
	t_connection		* c;
	char			* p, * tserver;

	ASSERT(server,NULL);
	tserver=xstrdup(server);
	p=std::strchr(tserver,':');
	if (p) {
		port=(unsigned short)std::strtoul(p+1,NULL,10);
		*p='\0';
	} else {
		port=def_port;
	}

	if ((sock=net_socket(PSOCK_SOCK_STREAM))<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error creating s2s socket");
		xfree(tserver);
		return NULL;
	}

	std::memset(&addr,0,sizeof(addr));
	addr.sin_family = PSOCK_AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr= net_inet_addr(tserver);
	xfree(tserver);

	eventlog(eventlog_level_info,__FUNCTION__,"try make s2s connection to {}",server);
	if (psock_connect(sock,(struct sockaddr *)&addr,sizeof(addr))<0) {
		if (psock_errno()!=PSOCK_EWOULDBLOCK && psock_errno() != PSOCK_EINPROGRESS) {
			eventlog(eventlog_level_error,__FUNCTION__,"error connecting to {} (psock_connect: {})",server,pstrerror(psock_errno()));
			psock_close(sock);
			return NULL;
		}
		connected=0;
		eventlog(eventlog_level_info,__FUNCTION__,"connection to s2s server {} is in progress",server);
	} else {
		connected=1;
		eventlog(eventlog_level_info,__FUNCTION__,"connected to s2s server {}",server);
	}
	laddr_len=sizeof(laddr);
	std::memset(&laddr,0,sizeof(laddr));
	ip=port=0;
	if (psock_getsockname(sock,(struct sockaddr *)&laddr,&laddr_len)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"unable to get local socket info");
	} else {
		if (laddr.sin_family != PSOCK_AF_INET) {
			eventlog(eventlog_level_error,__FUNCTION__,"got bad socket family {}",laddr.sin_family);
		} else {
			ip=ntohl(laddr.sin_addr.s_addr);
			port=ntohs(laddr.sin_port);
		}
	}
	if (!(c=d2cs_conn_create(sock,ip,port, ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port)))) {
		eventlog(eventlog_level_error,__FUNCTION__,"error create s2s connection");
		psock_close(sock);
		return NULL;
	}
	if (connected) {
		if (conn_add_fd(c,fdwatch_type_read, d2cs_server_handle_tcp)<0) {
		    eventlog(eventlog_level_error, __FUNCTION__, "error adding socket {} to fdwatch pool (max sockets?)",sock);
		    d2cs_conn_set_state(c,conn_state_destroy);
		    return NULL;
		}
		d2cs_conn_set_state(c,conn_state_init);
	} else {
		if (conn_add_fd(c, fdwatch_type_write, d2cs_server_handle_tcp)<0) {
		    eventlog(eventlog_level_error, __FUNCTION__, "error adding socket {} to fdwatch pool (max sockets?)",sock);
		    d2cs_conn_set_state(c,conn_state_destroy);
		    return NULL;
		}
		d2cs_conn_set_state(c,conn_state_connecting);
	}
	d2cs_conn_set_class(c,cclass);
	return c;
}
Exemplo n.º 22
0
extern int net_check_connected(int sock)
{
	int		err;
	psock_t_socklen	errlen;

	err = 0;
	errlen = sizeof(err);
	if (psock_getsockopt(sock,PSOCK_SOL_SOCKET, PSOCK_SO_ERROR, &err, &errlen)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error get socket option SO_ERROR (psock_getsockopt: %s)",pstrerror(psock_errno()));
		return -1;
	}
	if (errlen && err)
	       return -1;
	return 0;
}
Exemplo n.º 23
0
void dbs_server_loop(int lsocket)
{
	struct sockaddr_in sinRemote;
	int sd ;
	fd_set ReadFDs, WriteFDs, ExceptFDs;
	t_elem * elem;
	t_d2dbs_connection* it;
	BOOL bOK ;
	const char* pcErrorType ;
	struct timeval         tv;
	int highest_fd;
	psock_t_socklen nAddrSize = sizeof(sinRemote);
	
	while (1) {
#ifdef WIN32
		if (g_ServiceStatus<0 && kbhit() && getch()=='q')
			d2dbs_signal_quit_wrapper();
		
		if (g_ServiceStatus == 0) d2dbs_signal_quit_wrapper();
		
		while (g_ServiceStatus == 2) Sleep(1000);
#endif
		if (d2dbs_handle_signal()<0) break;
		dbs_handle_timed_events();
		highest_fd=dbs_server_setup_fdsets(&ReadFDs, &WriteFDs, &ExceptFDs, lsocket);

		tv.tv_sec  = 0;
		tv.tv_usec = SELECT_TIME_OUT;
		switch (psock_select(highest_fd+1, &ReadFDs, &WriteFDs, &ExceptFDs, &tv) ) {
			case -1:
				eventlog(eventlog_level_error,__FUNCTION__,"psock_select() failed : %s",strerror(psock_errno()));
				continue;
			case 0:
				continue;
			default:
				break;
		}

		if (PSOCK_FD_ISSET(lsocket, &ReadFDs)) {
			sd = psock_accept(lsocket, (struct sockaddr*)&sinRemote, &nAddrSize);
			if (sd == -1) {
				eventlog(eventlog_level_error,__FUNCTION__,"psock_accept() failed : %s",strerror(psock_errno()));
				return;
			}
			
			eventlog(eventlog_level_info,__FUNCTION__,"accepted connection from %s:%d , socket %d .",
				inet_ntoa(sinRemote.sin_addr) , ntohs(sinRemote.sin_port), sd);
			eventlog_step(prefs_get_logfile_gs(),eventlog_level_info,__FUNCTION__,"accepted connection from %s:%d , socket %d .",
				inet_ntoa(sinRemote.sin_addr) , ntohs(sinRemote.sin_port), sd);
			setsockopt_keepalive(sd);
			dbs_server_list_add_socket(sd, ntohl(sinRemote.sin_addr.s_addr));
			if (psock_ctl(sd,PSOCK_NONBLOCK)<0) {
				eventlog(eventlog_level_error,__FUNCTION__,"could not set TCP socket [%d] to non-blocking mode (closing connection) (psock_ctl: %s)", sd,strerror(psock_errno()));
				psock_close(sd);
			}
		} else if (PSOCK_FD_ISSET(lsocket, &ExceptFDs)) {
			eventlog(eventlog_level_error,__FUNCTION__,"exception on listening socket");
			/* FIXME: exceptions are not errors with TCP, they are out-of-band data */
			return;
		}
		
		LIST_TRAVERSE(dbs_server_connection_list,elem)
		{
			bOK = TRUE;
			pcErrorType = 0;
			
			if (!(it=elem_get_data(elem))) continue;
			if (PSOCK_FD_ISSET(it->sd, &ExceptFDs)) {
				bOK = FALSE;
				pcErrorType = "General socket error"; /* FIXME: no no no no no */
				PSOCK_FD_CLR(it->sd, &ExceptFDs);
			} else {
				
				if (PSOCK_FD_ISSET(it->sd, &ReadFDs)) {
					bOK = dbs_server_read_data(it);
					pcErrorType = "Read error";
					PSOCK_FD_CLR(it->sd, &ReadFDs);
				}
				
				if (PSOCK_FD_ISSET(it->sd, &WriteFDs)) {
					bOK = dbs_server_write_data(it);
					pcErrorType = "Write error";
					PSOCK_FD_CLR(it->sd, &WriteFDs);
				}
			}
			
			if (!bOK) {
				int	err;
				psock_t_socklen	errlen;
				
				err = 0;
				errlen = sizeof(err);
				if (psock_getsockopt(it->sd, PSOCK_SOL_SOCKET, PSOCK_SO_ERROR, &err, &errlen)==0) {
					if (errlen && err!=0) {
						eventlog(eventlog_level_error,__FUNCTION__,"data socket error : %s",strerror(err));
					}
				}
				dbs_server_shutdown_connection(it);
				list_remove_elem(dbs_server_connection_list,&elem);
			} else {
				if (dbs_packet_handle(it)==-1) {
					eventlog(eventlog_level_error,__FUNCTION__,"dbs_packet_handle() failed");
					dbs_server_shutdown_connection(it);
					list_remove_elem(dbs_server_connection_list,&elem);
				}
			}
		}
	}
Exemplo n.º 24
0
extern int net_recv_packet(int sock, t_packet * packet, unsigned int * currsize)
{
    int          addlen;
    unsigned int header_size;
    void *       temp;
    
    if (!packet)
    {
	eventlog(eventlog_level_error,"net_recv_packet","[%d] got NULL packet (closing connection)",sock);
	return -1;
    }
    if (!currsize)
    {
	eventlog(eventlog_level_error,"net_recv_packet","[%d] got NULL currsize (closing connection)",sock);
	return -1;
    }
    
    if ((header_size = packet_get_header_size(packet))>=MAX_PACKET_SIZE)
    {
	eventlog(eventlog_level_error,"net_recv_packet","[%d] could not determine header size (closing connection)",sock);
	return -1;
    }
    
    if (!(temp = packet_get_raw_data_build(packet,*currsize)))
    {
	eventlog(eventlog_level_error,"net_recv_packet","[%d] could not obtain raw data pointer at offset %u (closing connection)",sock,*currsize);
	return -1;
    }
    
    if (*currsize<header_size)
    {
	addlen = psock_recv(sock,
		            temp,
		            header_size-*currsize,
		            0);
    }
    else
    {
	unsigned int total_size=packet_get_size(packet);
	
	if (total_size<header_size)
	{
	    eventlog(eventlog_level_warn,"net_recv_packet","[%d] corrupted packet received (total_size=%u currsize=%u) (closing connection)",sock,total_size,*currsize);
	    return -1;
	}
	if (*currsize>=total_size)
	{
	    eventlog(eventlog_level_warn,"net_recv_packet","[%d] more data requested for already complete packet (total_size=%u currsize=%u) (closing connection)",sock,total_size,*currsize);
	    return -1;
	}
	
	addlen = psock_recv(sock,
		            temp,
		            total_size-*currsize,
		            0);
    }
    
    if (addlen==0)
    {
	eventlog(eventlog_level_debug,"net_recv_packet","[%d] remote host closed connection",sock);
	return -1;
    }
    if (addlen<0)
    {
        if (
#ifdef PSOCK_EINTR
	    psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
	    psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
	    psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ENOMEM
	    psock_errno()==PSOCK_ENOMEM ||
#endif
	    0) /* try later */
            return 0;
	if (
#ifdef PSOCK_ENOTCONN
	    psock_errno()==PSOCK_ENOTCONN ||
#endif
#ifdef PSOCK_ECONNRESET
	    psock_errno()==PSOCK_ECONNRESET ||
#endif
	    0)
	{
/*	    eventlog(eventlog_level_debug,"net_recv_packet","[%d] remote host closed connection (psock_recv: %s)",sock,strerror(psock_errno())); */
	    return -1; /* common error: close connection, but no message */
	}
	eventlog(eventlog_level_error,"net_recv_packet","[%d] receive error (closing connection) (psock_recv: %s)",sock,strerror(psock_errno()));
	return -1;
    }
    
    *currsize += addlen;
    
    if (*currsize>=header_size && *currsize==packet_get_size(packet))
	return 1;
    
    return 0;
}
Exemplo n.º 25
0
extern int udptest_send(t_connection const * c)
{
    t_packet *         upacket;
    struct sockaddr_in caddr;
    unsigned int       tries,successes;

    memset(&caddr,0,sizeof(caddr));
    caddr.sin_family = PSOCK_AF_INET;
    caddr.sin_port = htons(conn_get_game_port(c));
    caddr.sin_addr.s_addr = htonl(conn_get_game_addr(c));

    for (tries=successes=0; successes!=2 && tries<5; tries++)
    {
        if (!(upacket = packet_create(packet_class_udp)))
        {
            eventlog(eventlog_level_error,"udptest_send","[%d] could not allocate memory for packet",conn_get_socket(c));
            continue;
        }
        packet_set_size(upacket,sizeof(t_server_udptest));
        packet_set_type(upacket,SERVER_UDPTEST);
        bn_int_tag_set(&upacket->u.server_udptest.bnettag,BNETTAG);

        if (hexstrm)
        {
            fprintf(hexstrm,"%d: send class=%s[0x%02hx] type=%s[0x%04hx] ",
                    conn_get_game_socket(c),
                    packet_get_class_str(upacket),(unsigned int)packet_get_class(upacket),
                    packet_get_type_str(upacket,packet_dir_from_server),packet_get_type(upacket));
            fprintf(hexstrm,"from=%s ",
                    addr_num_to_addr_str(conn_get_game_addr(c),conn_get_game_port(c)));
            fprintf(hexstrm,"to=%s ",
                    addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port)));
            fprintf(hexstrm,"length=%u\n",
                    packet_get_size(upacket));
            hexdump(hexstrm,packet_get_raw_data(upacket,0),packet_get_size(upacket));
        }

        if (psock_sendto(conn_get_game_socket(c),
                         packet_get_raw_data_const(upacket,0),packet_get_size(upacket),
                         0,(struct sockaddr *)&caddr,(psock_t_socklen)sizeof(caddr))!=(int)packet_get_size(upacket))
            eventlog(eventlog_level_error,"udptest_send","[%d] failed to send UDPTEST to %s (attempt %u) (psock_sendto: %s)",conn_get_socket(c),addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),conn_get_game_port(c)),tries+1,strerror(psock_errno()));
        else
            successes++;

        packet_del_ref(upacket);
    }

    if (successes!=2)
        return -1;

    return 0;
}
Exemplo n.º 26
0
extern int net_socket(int type)
{
	int	sock;
	int	val;
	int     ipproto;

	if (type==PSOCK_SOCK_STREAM) {
		ipproto = PSOCK_IPPROTO_TCP;
	} else {
		ipproto = PSOCK_IPPROTO_UDP;
	}
	if ((sock=psock_socket(PSOCK_PF_INET, type, ipproto))<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error creating socket (psock_socket: %s)", pstrerror(psock_errno()));
		return -1;
	}
	val=1;
	if (psock_setsockopt(sock,PSOCK_SOL_SOCKET, PSOCK_SO_KEEPALIVE, &val, sizeof(val))<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error set socket option KEEPALIVE (psock_setsockopt: %s)",pstrerror(psock_errno()));
	}
	if (psock_ctl(sock,PSOCK_NONBLOCK)<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"error set socket mode to non-block (psock_ctl: %s)",pstrerror(psock_errno()));
		psock_close(sock);
		return -1;
	}
	return sock;
}