void CapstoneTokenizer::UpdateConfig() { SetConfig(ConfigBool("Disassembler", "Uppercase"), ConfigBool("Disassembler", "TabbedMnemonic"), ConfigBool("Disassembler", "ArgumentSpaces"), ConfigBool("Disassembler", "MemorySpaces")); }
void CreateNewAccountAndCharacter(char *name,char *password) { user_node *u; int account_id; if (ConfigBool(DEBUG_SMTP)) { dprintf("name = %s\n",name); dprintf("password = %s\n",password); } if (CreateAccount(name,password,ACCOUNT_NORMAL,&account_id) == False) { lprintf("CreateNewAccountAndCharacter tried to create account %s which already exists\n", name); return; } u = CreateNewUser(account_id,USER_CLASS); if (u == NULL) { eprintf("CreateNewAccountAndCharacter can't find just created user for account %i!\n", account_id); return; } lprintf("Created account %i (%s), object %i\n",account_id,name,u->object_id); }
void InitProfiling(void) { int i; if (done) return; kod_stat.num_interpreted = 0; kod_stat.num_interpreted_highest = 0; kod_stat.billions_interpreted = 0; kod_stat.num_messages = 0; kod_stat.num_top_level_messages = 0; kod_stat.system_start_time = GetTime(); kod_stat.interpreting_time = 0; kod_stat.interpreting_time_highest = 0; kod_stat.interpreting_time_over_second = 0; kod_stat.interpreting_time_message_id = INVALID_ID; kod_stat.interpreting_time_object_id = INVALID_ID; kod_stat.interpreting_time_posts = 0; kod_stat.message_depth_highest = 0; kod_stat.interpreting_class = INVALID_CLASS; kod_stat.debugging = ConfigBool(DEBUG_UNINITIALIZED); for (i=0;i<MAX_C_FUNCTION;i++) kod_stat.c_count[i] = 0; message_depth = 0; done = 1; }
void SendSMTPMessage(smtp_node *smtp,char *msg) { if (ConfigBool(DEBUG_SMTP)) dprintf("SMTP reply: %s\n",msg); SendSMTPBuffer(smtp,msg); SendSMTPBuffer(smtp,"\r\n"); }
void LoadAdminConstants(void) { FILE *constantsfile; char line[MAX_CONSTANTS_LINE]; int lineno; char *name_str, *value_str; int value; if (ConfigBool(CONSTANTS_ENABLED) == False) return; if ((constantsfile = fopen(ConfigStr(CONSTANTS_FILENAME), "rt")) == NULL) { eprintf("LoadAdminConstants can't open %s, no constants\n", ConfigStr(CONSTANTS_FILENAME)); return; } lineno = 0; while (fgets(line, MAX_CONSTANTS_LINE, constantsfile)) { lineno++; name_str = strtok(line, "= \t\n"); /* ignore blank lines */ if (name_str == NULL) continue; /* ignore comments lines */ if (strlen(name_str) > 1 && name_str[0] == '/' && name_str[1] == '/') continue; value_str = strtok(NULL, "= \t\n"); if (name_str == NULL || name_str[0] == '/') { eprintf("LoadAdminConstants error reading value on line %i\n", lineno); continue; } if (sscanf(value_str, "%i", &value) != 1) { eprintf("LoadAdminConstants error parsing integer on line %i\n", lineno); continue; } AddAdminConstant(name_str, value); } fclose(constantsfile); }
void HandleSMTPConnection(smtp_node *smtp) { HANDLE hThread; if (ConfigBool(DEBUG_SMTP)) dprintf("SMTP Connection: %s\n",smtp->source_name); hThread = (HANDLE) _beginthread(ThreadHandleSMTPConnection,0, (void *)smtp); SetThreadPriority(hThread,THREAD_PRIORITY_BELOW_NORMAL); }
void WriteStrChannel(int channel_id,char *s) { if (channel[channel_id].file != NULL) { fwrite(s, 1, strlen(s), channel[channel_id].file); if (ConfigBool(CHANNEL_FLUSH)) fflush(channel[channel_id].file); } WriteChannelBuffer(channel_id,s); }
void DeleteAccountFromBuffer(char *buf) { char *line; char *version,*name; account_node *a; version = name = NULL; line = strtok(buf,"\r\n"); while (line != NULL) { if (ConfigBool(DEBUG_SMTP)) { dprintf(": %i %s\n",strlen(line),line); Sleep(500); } if (strcmp(line,"VERSION:") == 0) version = strtok(NULL,"\r\n"); if (strcmp(line,"NAME:") == 0) name = strtok(NULL,"\r\n"); line = strtok(NULL,"\r\n"); } if (version == NULL) { eprintf("DeleteAccountFromBuffer got no version\n"); return; } if (strcmp(version,"1") != 0) { eprintf("DeleteAccountFromBuffer got version != 1 (%s)\n",version); return; } if (name == NULL) { eprintf("DeleteAccountFromBuffer got email w/o name\n"); return; } EnterServerLock(); a = GetAccountByName(name); if (a == NULL) eprintf("DeleteAccountFromBuffer got email w/name that's not a valid account %s\n",name); else PostThreadMessage(main_thread_id,WM_BLAK_MAIN_DELETE_ACCOUNT,0,a->account_id); LeaveServerLock(); }
void OpenDefaultChannels() { int i; for (i=0;i<NUM_CHANNELS;i++) { if (ConfigBool(channel_table[i].disk_config_id)) { channel[i].file = CreateFileChannel(i); if (channel[i].file == NULL) StartupPrintf("OpenDefaultChannels couldn't open file %s\n", channel_table[i].file_name); } else channel[i].file = NULL; } }
int AllocateObject(int class_id) { int old_objects; class_node *c; c = GetClassByID(class_id); if (c == NULL) { eprintf("AllocateObject can't find class id %i\n",class_id); return INVALID_OBJECT; } if (num_objects == max_objects) { old_objects = max_objects; max_objects = max_objects * 2; objects = (object_node *) ResizeMemory(MALLOC_ID_OBJECT,objects,old_objects*sizeof(object_node), max_objects*sizeof(object_node)); lprintf("AllocateObject resized to %i objects\n",max_objects); } objects[num_objects].object_id = num_objects; objects[num_objects].class_id = class_id; objects[num_objects].deleted = False; objects[num_objects].num_props = 1 + c->num_properties; objects[num_objects].p = (prop_type *)AllocateMemory(MALLOC_ID_OBJECT_PROPERTIES, sizeof(prop_type)*(1+c->num_properties)); if (ConfigBool(DEBUG_INITPROPERTIES)) { int i; prop_type p; p.id = 0; p.val.v.tag = TAG_INVALID; p.val.v.data = 0; for (i = 0; i < (1+c->num_properties); i++) { objects[num_objects].p[i] = p; } } return num_objects++; }
int CreateObject(int class_id,int num_parms,parm_node parms[]) { int new_object_id; class_node *c; new_object_id = AllocateObject(class_id); if (new_object_id == INVALID_OBJECT) return INVALID_OBJECT; /* set self = prop 0 */ objects[new_object_id].p[0].id = 0; objects[new_object_id].p[0].val.v.tag = TAG_OBJECT; objects[new_object_id].p[0].val.v.data = new_object_id; c = GetClassByID(class_id); if (c == NULL) /* can't ever be, because AllocateObject checks */ { eprintf("CreateObject can't find class id %i\n",class_id); return INVALID_OBJECT; } SetObjectProperties(new_object_id,c); /* might not be top level message, since can be called from blakod. If it really IS a top level message, then it better not post anything, since post messages won't be handled */ if (IsInterpreting()) SendBlakodMessage(new_object_id,CONSTRUCTOR_MSG,num_parms,parms); else SendTopLevelBlakodMessage(new_object_id,CONSTRUCTOR_MSG,num_parms,parms); if (ConfigBool(DEBUG_UNINITIALIZED)) { int i; for (i = 0; i < (1+c->num_properties); i++) if (objects[new_object_id].p[i].val.v.tag == TAG_INVALID) eprintf("Uninitialized properties after constructor, class %s\n", c->class_name); } return new_object_id; }
void ProcessSMTPLine(smtp_node *smtp) { int i; char *cmd; if (smtp->state == SMTP_DATA) { if (!stricmp(smtp->cmd,".\r\n")) { ProcessMessageDataDone(smtp); smtpprintf(smtp,"250 Ok, got the message"); /* dprintf("Sent ok, got message"); */ smtp->state = SMTP_READY; } else { if (smtp->cmd[0] == '.') AddSMTPDataLine(smtp,smtp->cmd+1); else AddSMTPDataLine(smtp,smtp->cmd); } return; } if (ConfigBool(DEBUG_SMTP)) dprintf("SMTP Command: %s\n",smtp->cmd); cmd = strtok(smtp->cmd," \t\r\n"); if (cmd == NULL) { return; } for (i=0;i<LEN_SMTP_TABLE;i++) { if (!stricmp(smtp_table[i].name,cmd)) { smtp_table[i].smtp_func(smtp); return; } } smtpprintf(smtp,"502 Command not handled"); }
void MySQLInit() { if (ConfigBool(MYSQL_ENABLED) == False) return; enabled = true; mysqlcon = mysql_init(NULL); if (mysqlcon == NULL) { dprintf("%s\n", mysql_error(mysqlcon)); return; } if (mysql_real_connect(mysqlcon, ConfigStr(MYSQL_HOST), ConfigStr(MYSQL_USERNAME), ConfigStr(MYSQL_PASSWORD), NULL, 0, NULL, 0) == NULL) { dprintf("Error connecting: %s\n", mysql_error(mysqlcon)); dprintf("host: %s user: %s pass: %s", ConfigStr(MYSQL_HOST), ConfigStr(MYSQL_USERNAME), ConfigStr(MYSQL_PASSWORD)); mysql_close(mysqlcon); return; } else { dprintf("connected to mysql host: %s user: %s", ConfigStr(MYSQL_HOST),ConfigStr(MYSQL_USERNAME) ); } //Check for valid schema here... char buf[100]; sprintf(buf, "USE %s", ConfigStr(MYSQL_DB)); if(mysql_query(mysqlcon, buf)) { dprintf("Error selecting databsae: %s\n", mysql_error(mysqlcon)); return; } else { dprintf("connected to mysql database: %s", ConfigStr(MYSQL_DB)); } connected = true; return; }
/* this function is run in its own thread */ void __cdecl ThreadHandleSMTPConnection(void *param) { smtp_node *smtp = (smtp_node *) param; /* gotta free the smtp node when done--allocated by AsyncSMTPSocketConnect in async.c */ smtpprintf(smtp,"220 %s Ready to go",GetLocalMachineName()); while (smtp->state != SMTP_QUIT && smtp->state != SMTP_ERROR) { ReadSMTPLine(smtp); } if (ConfigBool(DEBUG_SMTP)) dprintf("SMTP Disconnection: %s\n",smtp->source_name); ClearSMTPBuffers(smtp); closesocket(smtp->sock); FreeMemory(MALLOC_ID_SMTP,smtp,sizeof(smtp_node)); }
void AsyncSocketAccept(SOCKET sock,int event,int error,int connection_type) { SOCKET new_sock; SOCKADDR_IN acc_sin; /* Accept socket address - internet style */ int acc_sin_len; /* Accept socket address length */ SOCKADDR_IN peer_info; int peer_len; struct in_addr peer_addr; connection_node conn; session_node *s; if (event != FD_ACCEPT) { eprintf("AsyncSocketAccept got non-accept %i\n",event); return; } if (error != 0) { eprintf("AsyncSocketAccept got error %i\n",error); return; } acc_sin_len = sizeof acc_sin; new_sock = accept(sock,(struct sockaddr *) &acc_sin,&acc_sin_len); if (new_sock == SOCKET_ERROR) { eprintf("AcceptSocketConnections accept failed, error %i\n", GetLastError()); return; } peer_len = sizeof peer_info; if (getpeername(new_sock,(SOCKADDR *)&peer_info,&peer_len) < 0) { eprintf("AcceptSocketConnections getpeername failed error %i\n", GetLastError()); return; } memcpy(&peer_addr,(long *)&(peer_info.sin_addr),sizeof(struct in_addr)); memcpy(&conn.addr, &peer_addr, sizeof(struct in_addr)); sprintf(conn.name,"%s",inet_ntoa(peer_addr)); // Too out following line to prevent log files from becoming spammed with extra lines. // This line is extraneous because the outcome of the authentication is always posted to logs. // lprintf("Got connection from %s to be authenticated.\n", conn.name); if (connection_type == SOCKET_MAINTENANCE_PORT) { if (!CheckMaintenanceMask(&peer_info,peer_len)) { lprintf("Blocked maintenance connection from %s.\n", conn.name); closesocket(new_sock); return; } } else { if (!CheckBlockList(&peer_addr)) { lprintf("Blocked connection from %s.\n", conn.name); closesocket(new_sock); return; } } conn.type = CONN_SOCKET; conn.socket = new_sock; EnterServerLock(); s = CreateSession(conn); if (s != NULL) { StartAsyncSession(s); switch (connection_type) { case SOCKET_PORT : InitSessionState(s,STATE_SYNCHED); break; case SOCKET_MAINTENANCE_PORT : InitSessionState(s,STATE_MAINTENANCE); break; default : eprintf("AcceptSocketConnections got invalid connection type %i\n",connection_type); } /* need to do this AFTER s->conn is set in place, because the async call writes to that mem address */ if (ConfigBool(SOCKET_DNS_LOOKUP)) { s->conn.hLookup = StartAsyncNameLookup((char *)&peer_addr,s->conn.peer_data); } else { s->conn.hLookup = 0; } } LeaveServerLock(); }
void GameProcessSessionBuffer(session_node *s) { client_msg msg; unsigned short security; s->game->game_last_message_time = GetTime(); if (s->game->game_state != GAME_NORMAL) { GameSyncProcessSessionBuffer(s); return; } /* need to copy only as many bytes as we can hold */ while (s->receive_list != NULL) { if (PeekSessionBytes(s,HEADERBYTES,&msg) == False) return; if (msg.len != msg.len_verify) { /* dprintf("GPSB found len != len_verify %i %i\n",msg_len,msg_len_verify); */ GameSendResync(s); GameSyncInit(s); GameSyncProcessSessionBuffer(s); return; } if (msg.len > LEN_MAX_CLIENT_MSG) { eprintf("GameProcessSessionBuffer got message too long %i\n",msg.len); GameSendResync(s); GameSyncInit(s); GameSyncProcessSessionBuffer(s); return; } /* now read the header for real, plus the actual data */ if (ReadSessionBytes(s,msg.len+HEADERBYTES,&msg) == False) return; /* dprintf("got crc %08x\n",msg.crc16); */ security = GameRandomStreamsStep(s); /* dprintf("%08x is the next stream thing\n",security); */ security ^= msg.len; security ^= ((unsigned int)msg.data[0] << 4); security ^= GetCRC16(msg.data,msg.len); /* dprintf("%08x is the next stream thing after xor\n",security); */ if (msg.crc16 != security && !s->seeds_hacked) { s->seeds_hacked = True; if (ConfigBool(SECURITY_LOG_SPOOFS)) { lprintf("GameProcessSessionBuffer found invalid security account %i\n", s->account->account_id); } if (ConfigBool(SECURITY_HANGUP_SPOOFS)) { HangupSession(s); } // can't use the packet, so throw it away and go into resync mode GameSendResync(s); GameSyncInit(s); GameSyncProcessSessionBuffer(s); return; } if (msg.seqno != GetEpoch()) /* old sequence ok, just ignore */ { /* dprintf("Game got bad epoch from session %i\n",s->session_id); */ continue; } /* give up receive mutex, so the interface/socket thread can read data for us, even if doing something long (GC/save/reload sys) */ if (!ReleaseMutex(s->muxReceive)) eprintf("GPSB released mutex it didn't own in session %i\n",s->session_id); GameProtocolParse(s,&msg); if (WaitForSingleObject(s->muxReceive,10000) != WAIT_OBJECT_0) { eprintf("GPSB bailed waiting for mutex on session %i\n",s->session_id); return; } /* if hung up, don't touch */ if (s->hangup == True) return; if (s->state != STATE_GAME) return; if (s->game->game_state != GAME_NORMAL) return; } }
void InitSMTP(void) { if (ConfigBool(EMAIL_LISTEN) == True) AcceptSMTPSocketConnections(ConfigInt(EMAIL_PORT)); }
/* connection_type is either SOCKET_PORT or SOCKET_MAINTENANCE_PORT, so we keep track of what state to send clients into. */ void AcceptSocketConnections(int socket_port,int connection_type) { SOCKET sock; SOCKADDR_IN sin; struct linger xlinger; int xxx; sock = socket(AF_INET,SOCK_STREAM,0); if (sock == INVALID_SOCKET) { eprintf("AcceptSocketConnections socket() failed WinSock code %i\n", GetLastError()); closesocket(sock); return; } /* Set a couple socket options for niceness */ xlinger.l_onoff=0; if (setsockopt(sock,SOL_SOCKET,SO_LINGER,(char *)&xlinger,sizeof(xlinger)) < 0) { eprintf("AcceptSocketConnections error setting sock opts 1\n"); return; } xxx=1; if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&xxx,sizeof xxx) < 0) { eprintf("AcceptSocketConnections error setting sock opts 2\n"); return; } if (!ConfigBool(SOCKET_NAGLE)) { /* turn off Nagle algorithm--improve latency? */ xxx = TRUE; if (setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(char *)&xxx,sizeof xxx)) { eprintf("AcceptSocketConnections error setting sock opts 3\n"); return; } } memset(&sin,sizeof sin,0); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons((short)socket_port); if (bind(sock,(struct sockaddr *) &sin,sizeof(sin)) == SOCKET_ERROR) { eprintf("AcceptSocketConnections bind failed, WinSock error %i\n", GetLastError()); closesocket(sock); return; } if (listen(sock,5) < 0) /* backlog of 5 connects by OS */ { eprintf("AcceptSocketConnections listen failed, WinSock error %i\n", GetLastError()); closesocket(sock); return; } StartAsyncSocketAccept(sock,connection_type); /* when we get a connection, it'll call AsyncSocketAccept */ }
/* returns either RETURN_PROPAGATE or RETURN_NO_PROPAGATE. If no propagate, * then the return value in ret_val is good. */ int InterpretAtMessage(int object_id,class_node* c,message_node* m, int num_sent_parms, parm_node sent_parms[],val_type *ret_val) { opcode_type opcode; char opcode_char; char num_locals,num_parms; local_var_type local_vars; int parm_id; val_type parm_init_value; int i,j; char *inst_start; Bool found_parm; num_locals = get_byte(); num_parms = get_byte(); local_vars.num_locals = num_locals+num_parms; if (local_vars.num_locals > MAX_LOCALS) { dprintf("InterpretAtMessage found too many locals and parms for OBJECT %i CLASS %s MESSAGE %s (%s) aborting and returning NIL\n", object_id, c? c->class_name : "(unknown)", m? GetNameByID(m->message_id) : "(unknown)", BlakodDebugInfo()); (*ret_val).int_val = NIL; return RETURN_NO_PROPAGATE; } if (ConfigBool(DEBUG_INITLOCALS)) { parm_init_value.v.tag = TAG_INVALID; parm_init_value.v.data = 1; for (i = 0; i < local_vars.num_locals; i++) { local_vars.locals[i] = parm_init_value; } } /* both table and call parms are sorted */ j = 0; for (i=0;i<num_parms;i++) { parm_id = get_int(); /* match this with parameters */ parm_init_value.int_val = get_int(); /* look if we have a value for this parm */ found_parm = False; j = 0; /* don't assume sorted for now */ while (j < num_sent_parms) { if (sent_parms[j].name_id == parm_id) { /* assuming no RetrieveValue needed here, since InterpretCall does that for us */ local_vars.locals[i].int_val = sent_parms[j].value; found_parm = True; j++; break; } j++; } if (!found_parm) local_vars.locals[i].int_val = parm_init_value.int_val; } for(;;) /* returns when gets a blakod return */ { num_interpreted++; /* infinite loop check */ if (num_interpreted > ConfigInt(BLAKOD_MAX_STATEMENTS)) { bprintf("InterpretAtMessage interpreted too many instructions--infinite loop?\n"); dprintf("Infinite loop at depth %i\n", message_depth); dprintf(" OBJECT %i CLASS %s MESSAGE %s (%s) aborting and returning NIL\n", object_id, c? c->class_name : "(unknown)", m? GetNameByID(m->message_id) : "(unknown)", BlakodDebugInfo()); dprintf(" Local variables:\n"); for (i=0;i<local_vars.num_locals;i++) { dprintf(" %3i : %s %5i\n", i, GetTagName(local_vars.locals[i]), local_vars.locals[i].v.data); } (*ret_val).int_val = NIL; return RETURN_NO_PROPAGATE; } opcode_char = get_byte(); //memcpy(&opcode,&opcode_char,1); { char *ch=(char*)&opcode; *ch = opcode_char ; } /* use continues instead of breaks here since there is nothing after the switch, for efficiency */ switch (opcode.command) { case UNARY_ASSIGN : InterpretUnaryAssign(object_id,&local_vars,opcode); continue; case BINARY_ASSIGN : InterpretBinaryAssign(object_id,&local_vars,opcode); continue; case GOTO : inst_start = bkod - 1; /* we've read one byte of instruction so far */ InterpretGoto(object_id,&local_vars,opcode,inst_start); continue; case CALL : InterpretCall(object_id,&local_vars,opcode); continue; case RETURN : if (opcode.dest == PROPAGATE) return RETURN_PROPAGATE; else { int data; data = get_int(); *ret_val = RetrieveValue(object_id,&local_vars,opcode.source1,data); return RETURN_NO_PROPAGATE; } /* can't get here */ continue; default : bprintf("InterpretAtMessage found INVALID OPCODE command %i. die.\n", opcode.command); FlushDefaultChannels(); continue; } } }
/* returns the return value of the blakod */ int SendTopLevelBlakodMessage(int object_id,int message_id,int num_parms,parm_node parms[]) { int ret_val = 0; UINT64 start_time = 0; int interp_time = 0; int posts = 0; int accumulated_num_interpreted = 0; if (message_depth != 0) { eprintf("SendTopLevelBlakodMessage called with message_depth %i\n",message_depth); } kod_stat.debugging = ConfigBool(DEBUG_UNINITIALIZED); start_time = GetMilliCount(); kod_stat.num_top_level_messages++; trace_session_id = INVALID_ID; num_interpreted = 0; ret_val = SendBlakodMessage(object_id,message_id,num_parms,parms); while (post_q.next != post_q.last) { posts++; accumulated_num_interpreted += num_interpreted; num_interpreted = 0; if (accumulated_num_interpreted > 10*ConfigInt(BLAKOD_MAX_STATEMENTS)) { bprintf("SendTopLevelBlakodMessage too many instructions in posted followups\n"); dprintf("SendTopLevelBlakodMessage too many instructions in posted followups\n"); dprintf(" OBJECT %i CLASS %s MESSAGE %s (%i) some followups are being aborted\n", object_id, GetClassByID(GetObjectByID(object_id)->class_id)->class_name, GetNameByID(message_id), message_id); break; } /* posted messages' return value is ignored */ SendBlakodMessage(post_q.data[post_q.last].object_id,post_q.data[post_q.last].message_id, post_q.data[post_q.last].num_parms,post_q.data[post_q.last].parms); post_q.last = (post_q.last + 1) % MAX_POST_QUEUE; } interp_time = (int)(GetMilliCount() - start_time); kod_stat.interpreting_time += interp_time; if (interp_time > kod_stat.interpreting_time_highest) { kod_stat.interpreting_time_highest = interp_time; kod_stat.interpreting_time_message_id = message_id; kod_stat.interpreting_time_object_id = object_id; kod_stat.interpreting_time_posts = posts; } if (interp_time > 1000) { kod_stat.interpreting_time_over_second++; kod_stat.interpreting_time_message_id = message_id; kod_stat.interpreting_time_object_id = object_id; kod_stat.interpreting_time_posts = posts; } if (num_interpreted > kod_stat.num_interpreted_highest) kod_stat.num_interpreted_highest = num_interpreted; kod_stat.num_interpreted += num_interpreted; if (kod_stat.num_interpreted > 1000000000L) { kod_stat.num_interpreted -= 1000000000L; kod_stat.billions_interpreted++; } if (message_depth != 0) { eprintf("SendTopLevelBlakodMessage returning with message_depth %i\n",message_depth); } return ret_val; }
void QBeaEngine::UpdateConfig() { _bLongDataInst = ConfigBool("Disassembler", "LongDataInstruction"); _tokenizer.UpdateConfig(); }
/* connection_type is either SOCKET_PORT or SOCKET_MAINTENANCE_PORT, so we keep track of what state to send clients into. */ void AcceptSocketConnections(int socket_port,int connection_type) { SOCKET sock; SOCKADDR_IN6 sin; struct linger xlinger; int xxx; sock = socket(AF_INET6,SOCK_STREAM,0); if (sock == INVALID_SOCKET) { eprintf("AcceptSocketConnections socket() failed WinSock code %i\n", GetLastError()); closesocket(sock); return; } /* Make sure this is a IPv4/IPv6 dual stack enabled socket */ xxx = 0; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&xxx, sizeof(xxx)) < 0) { eprintf("AcceptSocketConnections error setting sock opts: IPV6_V6ONLY\n"); return; } /* Set a couple socket options for niceness */ xlinger.l_onoff=0; if (setsockopt(sock,SOL_SOCKET,SO_LINGER,(char *)&xlinger,sizeof(xlinger)) < 0) { eprintf("AcceptSocketConnections error setting sock opts: SO_LINGER\n"); return; } xxx=1; if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&xxx,sizeof xxx) < 0) { eprintf("AcceptSocketConnections error setting sock opts: SO_REUSEADDR\n"); return; } if (!ConfigBool(SOCKET_NAGLE)) { /* turn off Nagle algorithm--improve latency? */ xxx = true; if (setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(char *)&xxx,sizeof xxx)) { eprintf("AcceptSocketConnections error setting sock opts: TCP_NODELAY\n"); return; } } memset(&sin,sizeof sin,0); sin.sin6_family = AF_INET6; sin.sin6_addr = in6addr_any; sin.sin6_flowinfo = 0; sin.sin6_scope_id = 0; sin.sin6_port = htons((short)socket_port); if (bind(sock,(struct sockaddr *) &sin,sizeof(sin)) == SOCKET_ERROR) { eprintf("AcceptSocketConnections bind failed, WinSock error %i\n", GetLastError()); closesocket(sock); return; } if (listen(sock,5) < 0) /* backlog of 5 connects by OS */ { eprintf("AcceptSocketConnections listen failed, WinSock error %i\n", GetLastError()); closesocket(sock); return; } StartAsyncSocketAccept(sock,connection_type); /* when we get a connection, it'll call AsyncSocketAccept */ }