//return true if fail
bool networking::init(int port) {
	//init winsock
	if(WSAStartup(MAKEWORD(2,0),&wsaData)!= 0) {
		fprintf(stderr,"Error: WSAStartup() faild");
		return true;
	}

	//create tcp listen socket
	if((srvr_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))== SOCKET_ERROR) {
		fprintf(stderr, "Error: socket() failed with error %d\n", WSAGetLastError());
		shutdown_close(srvr_socket);
		return true;
	}

	//construct local address
	memset(&srvr_addr,0,sizeof(srvr_addr));
	srvr_addr.sin_family = AF_INET;
	srvr_addr.sin_addr.s_addr = INADDR_ANY;
	srvr_addr.sin_port = htons(port);

	//bind local address
	if(bind(srvr_socket, (struct sockaddr *) &srvr_addr,sizeof(srvr_addr)) == SOCKET_ERROR) {
		fprintf(stderr,"Error: socket() faild with error %d",WSAGetLastError());
		shutdown_close(srvr_socket);
		return true;
	}

	if(listen(srvr_socket,1) == SOCKET_ERROR) {
		printf("listen failed with error: %d\n",WSAGetLastError());
		shutdown_close(srvr_socket);
		return true;
	}
	return false;
}
bool networking::update() {
	FD_ZERO(&fd);
	FD_SET(srvr_socket,&fd);
	int temp = 0;

	if((result = select(0,&fd,0,0,&instant)) == SOCKET_ERROR) {
		printf("select failed with error: %d\n",WSAGetLastError());
		shutdown_close(srvr_socket);
		return true;
	}
	if( result == 1) {
		if(curClients < maxClients) {
			while(bActive[temp]) {
				++temp;
			}
			clients[temp] = accept(srvr_socket,(sockaddr*)&clnt_addr,&addr_len);
			if(clients[temp] == INVALID_SOCKET) {
				printf("accept failed with error: %d\n",WSAGetLastError());
				shutdown_close(clients[temp]);
				return true;
			} else {
				bActive[temp] = true;
				clnt_addr[temp];
				++curClients;
			}
		}
	}
	if(curClients > 0) {
		FDClient();
		if((result = select(0,&fd,0,0,&instant)) == SOCKET_ERROR) {

		} else if(result > 0) {
			for(int i = 0; i < fd.fd_count; ++i) {
				if ((recv_msg_len = recvfrom(fd.fd_array[i], msgs[i].msg, MYBUFSIZE, 0,
					(struct sockaddr *) &clnt_addr[i], &addr_len )) == SOCKET_ERROR) {
						//disconnect client
						printf("recvfrom() failed with error: %d\n",WSAGetLastError());
						msgs[i].msgLength = 0;
						for(int z = 0; z < maxClients;++z) {
							if(clients[z] == fd.fd_array[i]) {
								shutdown_close(clients[z]);
								bActive[z] = false;
								--curClients;
								printf("client %d disconected\n",z);
							}
						}
				} else {
					//handel tcp msg
					msgs[i].msgLength = recv_msg_len;
					printf("%d\n",curClients);
					for(int z = 0; z < msgs[i].msgLength;++z)
						std::cout<<msgs[i].msg[z];
					printf("\n");
				}
			}
		}
	}
	return false;
};
bool networking::shutdown() {
	printf("shutting down server\n");
	for(int i = 0; i < maxClients; ++i) {
		if(bActive[i])
			shutdown_close(clients[i]);
	}
	shutdown_close(srvr_socket);
	printf("WSACleanup\n");
	WSACleanup();
	return true;
}
void shutdowndccchat(dccchat_t *chat, int flush)
{
  if (chat->status != DCCCHAT_UNUSED)
    {
      if (flush)
        {
          flushdccchat(chat);
        }
      
      usleep(100*1000);
      shutdown_close(chat->con.clientsocket);
      mydelete(chat->groups);
      mydelete(chat->hostmask);
      mydelete(chat->nick);
      mydelete(chat->con.localaddr);
      mydelete(chat->con.remoteaddr);
      ir_boutput_delete(&chat->boutput);

      if (chat->status == DCCCHAT_LISTENING)
        ir_listen_port_connected(chat->con.localport);

#ifdef USE_UPNP
      if (gdata.upnp_router && (chat->con.family == AF_INET))
        upnp_rem_redir(chat->con.localport);
#endif /* USE_UPNP */

      memset(chat, 0, sizeof(dccchat_t));
      chat->con.clientsocket = FD_UNUSED;
      chat->status = DCCCHAT_UNUSED;
      
      gdata.num_dccchats--;
    }
  return;
}
bool networking::sendMSGs() {
	int temp = 0;
	FDClient();
	if((result = select(0,0,&fd,0,&wait)) == SOCKET_ERROR) {

	} else if(result > 0) {
		for(int i = 0; i < fd.fd_count; ++i) {
			temp = 0;
			while(clients[temp] != fd.fd_array[i])
				++temp;
			if(sendto(fd.fd_array[i], msgs[temp].msg, msgs[temp].msgLength, 0,(sockaddr *) &clnt_addr[temp], addr_len) == SOCKET_ERROR) {
				printf("sendto() failed with error: %d\n",WSAGetLastError());
				//disconnect client
				for(int z = 0; z < maxClients;++z) {
					if(clients[z] == fd.fd_array[i]) {
						shutdown_close(clients[z]);
						bActive[z] = false;
						--curClients;
						printf("client %d disconected\n",z);
					}
				}
			}
		}
	}
	return false;
}
void shutdown_close_and_exit(SOCKET s) {
	shutdown_close(s);
	exit(1);
}
void t_closeconn(transfer * const t, const char *msg, int errno1)
{
  gnetwork_t *backup;
  
  updatecontext();
  
  if (errno1)
    {
      ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW,
              "XDCC [%02i:%s on %s]: Connection closed: %s (%s)",
              t->id, t->nick, gdata.networks[ t->net ].name, msg, strerror(errno1));
    }
  else
    {
      ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW,
              "XDCC [%02i:%s on %s]: Connection closed: %s",
              t->id, t->nick, gdata.networks[ t->net ].name, msg);
    }
  
  if (t->tr_status == TRANSFER_STATUS_DONE)
    {
      return;
    }
  
  if (gdata.debug > 0)
    {
      ioutput(OUT_S, COLOR_YELLOW,
              "clientsock = %d", t->con.clientsocket);
    }
  
#ifdef HAVE_MMAP
  if (t->mmap_info)
    {
      t->mmap_info->ref_count--;
      if (!t->mmap_info->ref_count)
        {
          int callval_i;
          callval_i = munmap(t->mmap_info->mmap_ptr, t->mmap_info->mmap_size);
          if (callval_i < 0)
            {
              outerror(OUTERROR_TYPE_WARN, "Couldn't munmap(): %s",
                       strerror(errno));
            }
          irlist_delete(&t->xpack->mmaps, t->mmap_info);
        }
      t->mmap_info = NULL;
    }
#endif
  
  if (t->con.listensocket != FD_UNUSED && t->con.listensocket > 2)
    {
      event_close(t->con.listensocket);
      t->con.listensocket = FD_UNUSED;
    }
  if (t->con.clientsocket != FD_UNUSED && t->con.clientsocket > 2)
    {
      shutdown_close(t->con.clientsocket);
      t->con.clientsocket = FD_UNUSED;
    }
  t->xpack->file_fd_count--;
  if (!t->xpack->file_fd_count && (t->xpack->file_fd != FD_UNUSED))
    {
      close(t->xpack->file_fd);
      t->xpack->file_fd = FD_UNUSED;
      t->xpack->file_fd_location = 0;
    }
  
  if (t->tr_status == TRANSFER_STATUS_LISTENING)
    ir_listen_port_connected(t->con.localport);

#ifdef USE_UPNP
  if (gdata.upnp_router && (t->con.family == AF_INET))
    upnp_rem_redir(t->con.localport);
#endif /* USE_UPNP */

  t->tr_status = TRANSFER_STATUS_DONE;
  
  backup = gnetwork;
  gnetwork = &(gdata.networks[t->net]);
  if (errno1)
    {
      notice(t->nick, "** Closing Connection: %s (%s)", msg, strerror(errno1));
    }
  else
    {
      notice(t->nick, "** Closing Connection: %s", msg);
    }
  gnetwork = backup;
}
void t_flushed (transfer * const t)
{
  ir_uint64 timetookms;
  char *tempstr;
  
  updatecontext();
  
  if (t->lastack < t->xpack->st_size)
    {
      return;
    }
  
  tempstr = mymalloc(maxtextlength);
  tempstr[0] = 0;
  
  timetookms = gdata.curtimems - t->connecttimems;
  if (timetookms < 1U)
    {
      timetookms = 1;
    }
  
  if (timetookms > (60*60*1000U))
    {
      snprintf(tempstr+strlen(tempstr), maxtextlength-strlen(tempstr),
               " %" LLPRINTFMT "u hr", timetookms/60/60/1000);
    }
  
  if ((timetookms%(60*60*1000U)) > (60*1000U))
    {
      snprintf(tempstr+strlen(tempstr), maxtextlength-strlen(tempstr),
               " %" LLPRINTFMT "u min", (timetookms%(60*60*1000))/60/1000);
    }
  
  snprintf(tempstr+strlen(tempstr), maxtextlength-strlen(tempstr),
           " %" LLPRINTFMT "u.%03" LLPRINTFMT "u sec", (timetookms%(60*1000))/1000, (timetookms%1000));
  
  ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW,
          "XDCC [%02i:%s on %s]: Transfer Completed (%" LLPRINTFMT "d kB,%s, %0.1f kB/sec)",
          t->id, t->nick, gdata.networks[ t->net ].name,
          (t->xpack->st_size-t->startresume)/1024,
          tempstr,
          ((float)(t->xpack->st_size-t->startresume))/1024.0/((float)timetookms/1000.0));
  
  ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW,
          "Log: Pack %u, Nick %s" ", Network %s" ", Sent %" LLPRINTFMT "d kB" ", Recv %" LLPRINTFMT "d kB" ", File %s",
          number_of_pack(t->xpack),
          t->nick,
          gdata.networks[ t->net ].name,
          (t->xpack->st_size-t->startresume)/1024, t->bytesgot/1024,
          t->xpack->desc );
  
  if (t->quietmode == 0)
    {
      if (t->xpack->has_md5sum)
        {
          notice(t->nick, "** Transfer Completed (%" LLPRINTFMT "d kB,%s, %0.1f kB/sec, md5sum: " MD5_PRINT_FMT ")",
                 (t->xpack->st_size-t->startresume)/1024,
                 tempstr,
                 ((float)(t->xpack->st_size-t->startresume))/1024.0/((float)timetookms/1000.0),
                 MD5_PRINT_DATA(t->xpack->md5sum));
        }
      else
        {
          notice(t->nick, "** Transfer Completed (%" LLPRINTFMT "d kB,%s, %0.1f kB/sec)",
                 (t->xpack->st_size-t->startresume)/1024,
                 tempstr,
                 ((float)(t->xpack->st_size-t->startresume))/1024.0/((float)timetookms/1000.0));
        }
    }
  if (gdata.download_completed_msg)
    {
      notice_slow(t->nick, "%s", gdata.download_completed_msg);
    }
  
  if ( ((float)(t->xpack->st_size-t->startresume))/1024.0/((float)timetookms/1000.0) > gdata.record )
    {
      gdata.record = ((float)(t->xpack->st_size-t->startresume))/1024.0/((float)timetookms/1000.0);
    }
  
  if (gdata.debug > 0)
    {
      ioutput(OUT_S, COLOR_YELLOW, "clientsock = %d", t->con.clientsocket);
    }
  shutdown_close(t->con.clientsocket);
  t->xpack->file_fd_count--;
  if (!t->xpack->file_fd_count && (t->xpack->file_fd != FD_UNUSED))
    {
      close(t->xpack->file_fd);
      t->xpack->file_fd = FD_UNUSED;
      t->xpack->file_fd_location = 0;
    }
  t->tr_status = TRANSFER_STATUS_DONE;
  t->xpack->gets++;
  
  if ((t->xpack->dlimit_max != 0) && (t->xpack->gets >= t->xpack->dlimit_used))
    {
      ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW, "Reached Pack Download Limit %u for %s",
              t->xpack->dlimit_max, t->xpack->desc);
       
      /* remove queued users */
      queue_pack_limit(&gdata.mainqueue, t->xpack);
      queue_pack_limit(&gdata.idlequeue, t->xpack);
    }
  
  mydelete(tempstr);
}
Exemple #9
0
/* find a free port and open a new socket for an incoming connection */
unsigned int open_listen(int family, ir_sockaddr_union_t *listenaddr, int *listen_socket, unsigned int port, unsigned int reuse, unsigned int search, const char *vhost)
{
  int rc;
  int tempc;
  SIGNEDSOCK int addrlen;

  updatecontext();

  if (vhost != NULL) {
    family = strchr(vhost, ':') ? AF_INET6 : AF_INET;
  }
  *listen_socket = socket(family, SOCK_STREAM, 0);
  if (*listen_socket < 0) {
    outerror(OUTERROR_TYPE_WARN_LOUD,
             "Could Not Create Socket, Aborting: %s", strerror(errno));
    *listen_socket = FD_UNUSED;
    return 1;
  }

  if (reuse) {
    tempc = 1;
    setsockopt(*listen_socket, SOL_SOCKET, SO_REUSEADDR, &tempc, sizeof(int));
  }

  bzero((char *) listenaddr, sizeof(ir_sockaddr_union_t));
  if (family == AF_INET) {
    addrlen = sizeof(struct sockaddr_in);
    listenaddr->sin.sin_family = AF_INET;
    listenaddr->sin.sin_addr.s_addr = INADDR_ANY;
    listenaddr->sin.sin_port = htons(port);
  } else {
    addrlen = sizeof(struct sockaddr_in6);
    listenaddr->sin6.sin6_family = AF_INET6;
    listenaddr->sin6.sin6_port = htons(port);
  }

  bind_vhost(listenaddr, family, vhost);

  if (search) {
    rc = ir_bind_listen_socket(*listen_socket, listenaddr);
  } else {
    rc = bind(*listen_socket, &(listenaddr->sa), addrlen);
  }

  if (rc < 0) {
    outerror(OUTERROR_TYPE_WARN_LOUD,
             "Couldn't Bind to Socket, Aborting: %s", strerror(errno));
    shutdown_close(*listen_socket);
    *listen_socket = FD_UNUSED;
    return 1;
  }

  if (listen(*listen_socket, 1) < 0) {
    outerror(OUTERROR_TYPE_WARN_LOUD, "Couldn't Listen, Aborting: %s", strerror(errno));
    shutdown_close(*listen_socket);
    *listen_socket = FD_UNUSED;
    return 1;
  }

#ifdef USE_UPNP
  if (gdata.upnp_router) {
    my_get_upnp_data(&(listenaddr->sa));
  }
#endif /* USE_UPNP */
  return 0;
}
Exemple #10
0
/* accept incoming connection */
static void telnet_accept(unsigned int i)
{
  gnetwork_t *backup;
  char *msg;
  dccchat_t *chat;
  SIGNEDSOCK int addrlen;

  updatecontext();

  chat = irlist_add(&gdata.dccchats, sizeof(dccchat_t));
  chat->name = "telnet"; /* NOTRANSLATE */
  chat->status = DCCCHAT_UNUSED;
  chat->con.family = telnet_family[i];
  if (chat->con.family != AF_INET) {
    addrlen = sizeof (struct sockaddr_in6);
    chat->con.clientsocket = accept(telnet_listen[i], &(chat->con.remote.sa), &addrlen);
  } else {
    addrlen = sizeof (struct sockaddr_in);
    chat->con.clientsocket = accept(telnet_listen[i], &(chat->con.remote.sa), &addrlen);
  }
  if (chat->con.clientsocket < 0) {
    outerror(OUTERROR_TYPE_WARN, "Accept Error, Aborting: %s", strerror(errno));
    return;
  }

  if (set_socket_nonblocking(chat->con.clientsocket, 1) < 0 ) {
    outerror(OUTERROR_TYPE_WARN, "Couldn't Set Non-Blocking");
  }

  addrlen = sizeof(chat->con.local);
  if (getsockname(chat->con.clientsocket, &(chat->con.local.sa), &addrlen) < 0) {
    outerror(OUTERROR_TYPE_WARN_LOUD, "Couldn't get sock name: %s", strerror(errno));
    shutdown_close(chat->con.clientsocket);
    chat->con.clientsocket = FD_UNUSED;
    return;
  }

  ++(gdata.num_dccchats);
  chat->status = DCCCHAT_AUTHENTICATING;
  chat->net = 0;
  chat->nick = mystrdup("telnet"); /* NOTRANSLATE */
  chat->hostmask = to_hostmask(chat->nick, "telnet"); /* NOTRANSLATE */
  chat->con.localport = gdata.telnet_port;
  chat->con.connecttime = gdata.curtime;
  chat->con.lastcontact = gdata.curtime;

  msg = mymalloc(maxtextlength);
  my_getnameinfo(msg, maxtextlength -1, &(chat->con.remote.sa));
  chat->con.localaddr = mystrdup(msg);
  my_getnameinfo(msg, maxtextlength -1, &(chat->con.local.sa));
  chat->con.remoteaddr = mystrdup(msg);
  ioutput(OUT_S|OUT_L|OUT_D, COLOR_MAGENTA,
          "Telnet connection received from %s",  msg);
  mydelete(msg);

  if (is_in_badip(&(chat->con.remote))) {
    shutdowndccchat(chat, 0);
    return;
  }

  if (irlist_size(&gdata.telnet_allow) > 0) {
    if (!verify_cidr(&gdata.telnet_allow, &(chat->con.remote))) {
      shutdowndccchat(chat, 0);
      return;
    }
  }

  if (verify_cidr(&gdata.telnet_deny, &(chat->con.remote))) {
    shutdowndccchat(chat, 0);
    return;
  }

  ir_boutput_init(&chat->boutput, chat->con.clientsocket, 0);

  backup = gnetwork;
  gnetwork = &(gdata.networks[chat->net]);
  setup_chat_banner(chat);
  gnetwork = backup;
}