void *openspy_mod_run(modLoadOptions *options) { #ifdef _WIN32 WSADATA wsdata; WSAStartup(MAKEWORD(1,0),&wsdata); #endif fd_set rset; memcpy(&servoptions,options,sizeof(modLoadOptions)); int num_instances = options->getConfInt(options->moduleArray,"numinstances"); char buff[1024]; int len; struct timeval timeout; memset(&timeout,0,sizeof(struct timeval)); if(num_instances < 1) return NULL; int *sockets = (int *)malloc(num_instances * sizeof(int)); struct sockaddr_in *si_me = (struct sockaddr_in *)malloc(num_instances * sizeof(struct sockaddr_in)); for(int i=0;i<num_instances;i++) { if((sockets[i] = socket(AF_INET,SOCK_DGRAM, IPPROTO_UDP)) == -1) { servoptions.logMessageProc(moduleInfo.name,LOGLEVEL_ERROR,"Error creating socket for instance %d\n",i+1); return NULL; } si_me[i].sin_family = AF_INET; si_me[i].sin_port = htons(MATCHUP_PORT); si_me[i].sin_addr.s_addr = getIP(i); if(bind(sockets[i],(struct sockaddr *)&si_me[i],sizeof(struct sockaddr)) == -1) { servoptions.logMessageProc(moduleInfo.name,LOGLEVEL_ERROR,"Error binding address for socket instance %d\n",i+1); return NULL; } } for(;;) { struct sockaddr_in si_other; socklen_t slen = sizeof(struct sockaddr_in); int rsock = getnfds(&rset,sockets,num_instances); timeout.tv_sec = 5; timeout.tv_usec = 0; if(select(rsock+1, &rset, NULL, NULL, &timeout) < 0) continue; for(int i=0;i<num_instances;i++) { if(FD_ISSET(sockets[i],&rset)) { len = recvfrom(sockets[i],(char *)&buff,sizeof(buff),0,(struct sockaddr *)&si_other,&slen); handleConnection(sockets[i], (struct sockaddr_in *)&si_other, i+1, (char *)&buff, len); } } checkTimeouts(); } return NULL; }
void *openspy_mod_run(modLoadOptions *options) { int sda,sd; socklen_t psz; fd_set rset; struct sockaddr_in peer; struct sockaddr_in user; memset(&peer,0,sizeof(peer)); int on=1; memcpy(&servoptions,options,sizeof(modLoadOptions)); conn = mysql_init(NULL); mysql_options(conn,MYSQL_OPT_RECONNECT, (char *)&on); /* Connect to database */ if (!mysql_real_connect(conn, servoptions.mysql_server, servoptions.mysql_user, servoptions.mysql_password, servoptions.mysql_database, 0, NULL, CLIENT_MULTI_RESULTS)) { fprintf(stderr, "%s\n", mysql_error(conn)); return NULL; } peer.sin_port = htons(LEGACYMSPORT); peer.sin_family = AF_INET; peer.sin_addr.s_addr = servoptions.bindIP; sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) return NULL; if(bind(sd, (struct sockaddr *)&peer, sizeof(struct sockaddr_in)) < 0) return NULL; if(listen(sd, SOMAXCONN) < 0) return NULL; struct timeval timeout; memset(&timeout,0,sizeof(struct timeval)); for(;;) { int hsock; FD_ZERO(&rset); FD_SET(sd, &rset); hsock = getnfds(&rset); if(hsock < sd) hsock = sd; timeout.tv_sec = SB_TIMEOUT_TIME; if(select(hsock+1, &rset, NULL, NULL, &timeout) < 0) continue; if(FD_ISSET(sd, &rset)) { } else { processClients(&rset); continue; } psz = sizeof(struct sockaddr_in); sda = accept(sd, (struct sockaddr *)&user, &psz); if(sda <= 0) continue; if(!do_db_check()) { close(sda); continue; //TODO: send database error message } boost::shared_ptr<Client> c = boost::make_shared<Client>(sda,(struct sockaddr_in *)&user); boost::container::stable_vector< boost::shared_ptr<Client> >::iterator iterator=server.client_list.begin(); boost::container::stable_vector< boost::shared_ptr<Client> >::iterator end=server.client_list.end(); for(;;) { if(iterator == end) { server.client_list.push_back(c); break; } else if(!*iterator) { *iterator = c; break; } else ++iterator; } } }