void start_client() { status = S_INIT; while (true) { switch(status) { case S_INIT: handle_init(); break; case S_EXIT: handle_exit(); return; case S_LOGIN: handle_login(); break; case S_REGISTER: handle_register(); break; case S_VERIFIED: handle_verified(); break; case S_ORDER: handle_order(); break; case S_QUERY_ORDER: handle_query_orders(); break; case S_QUERY: handle_query(); default: break; } } }
int MPI_Comm_create_endpoints(MPI_Comm parent_comm, int num_endpoints, MPI_Info info, MPI_Comm out_comm_hdls[]) { int* num_ep_list; int tot_endpoints = 0; int local_epid, global_epid = 0; int i; /* Return error if requested endpoints greater than servers */ if (num_endpoints > max_ep) return MPI_ERR_UNKNOWN; /* Map endpoints to servers */ /* Step 1/3: Gather total number of endpoints requested by all application tasks in the parent communicator parent_comm */ num_ep_list = (int*)malloc(num_tasks*sizeof(int)); ASSERT(num_ep_list != NULL); PMPI_Allgather(&num_endpoints, 1, MPI_INT, (void*)num_ep_list, 1, MPI_INT, parent_comm); /* Step 2/3: Create communicator handle objects */ for (i = 0; i < num_tasks; i++) { tot_endpoints += num_ep_list[i]; if (i < taskid) global_epid += num_ep_list[i]; } for (local_epid = 0; local_epid < num_endpoints; local_epid++) { out_comm_hdls[local_epid] = (MPI_Comm) handle_register(COMM_EP, MPI_COMM_NULL, parent_comm, num_endpoints, local_epid, tot_endpoints, global_epid, NULL, NULL); global_epid++; } /* Step 3/3: */ client_multiplex_endpoints(max_ep, num_tasks, num_endpoints, num_ep_list, out_comm_hdls); PMPI_Barrier(parent_comm); free(num_ep_list); return MPI_SUCCESS; }
void EPLIB_split_comm(MPI_Comm parentcomm, int color, int key, MPI_Comm newcomm) { if (max_ep == 0) return; MPI_Comm* worldcomm = NULL, *peercomm = NULL; MALLOC_ALIGN(worldcomm, max_ep * sizeof(MPI_Comm), CACHELINE_SIZE); MALLOC_ALIGN(peercomm, max_ep * sizeof(MPI_Comm), CACHELINE_SIZE); for (int i = 0; i < max_ep; i++) { worldcomm[i] = MPI_COMM_NULL; peercomm[i] = MPI_COMM_NULL; } cqueue_create_server_comm(parentcomm, color, key, worldcomm, peercomm); handle_register(COMM_REG, newcomm, parentcomm, max_ep, 0, num_tasks, taskid, worldcomm, peercomm); free(worldcomm); free(peercomm); }
/* parse client's order */ int parse_clnt_pack(SSL *ssl,SFT_PACK *clnt_pack,sqlite3 *db) { int ret = 0; int n = order_isexist(clnt_pack->order); if (n < 0) { fprintf(stderr,"%d:order is not exist!\n",clnt_pack->order); return -1; } switch(clnt_pack->order) { case CIN: handle_login(ssl,clnt_pack,db);break; case CREG: handle_register(ssl,clnt_pack,db);break; case CMODIFY_PASSWD: handle_modify_passwd(ssl,clnt_pack,db);break; case CSCS: handle_scan_dir(ssl,clnt_pack);break; case CUP: handle_recv_file(ssl,clnt_pack);break; case CDOWN: handle_send_file(ssl,clnt_pack);break; case COUT: handle_logout(ssl,clnt_pack); ret=COUT;break; default: fprintf(stderr,"%d:null order:!\n",clnt_pack->order); ret = -1;break; } return ret; }
void pim_interface::data_available(const sockaddr_in6 *src, const sockaddr_in6 *dst) { pim_message *pimmsg = g_mrd->ipktb->header<pim_message>(); int len = g_mrd->ipktb->rlength; m_stats.counter(AllCount, RX)++; if (pimmsg->type() != pim_msg_register && should_log(MESSAGE_SIG)) { log().xprintf("%s message from %{addr} to %{addr} len %u\n", pimmsg->type_name(), src->sin6_addr, dst->sin6_addr, (uint32_t)len); } if (pimmsg->type() == pim_msg_register) len = sizeof(pim_register_message); if (!(pimmsg->has_valid_checksum(src->sin6_addr, dst->sin6_addr, len) || (pimmsg->type() == pim_msg_register && pimmsg->has_valid_checksum(src->sin6_addr, dst->sin6_addr, g_mrd->ipktb->rlength)))) { m_stats.counter(AllCount, Bad)++; if (should_log(MESSAGE_ERR)) { log().xprintf("Dropping message from %{addr} to %{addr}" " len %u: Bad Checksum\n", src->sin6_addr, dst->sin6_addr, (uint32_t)g_mrd->ipktb->rlength); } return; } if (dst->sin6_addr == pim_all_routers) { if ((int)src->sin6_scope_id != owner()->index()) { if (should_log(MESSAGE_ERR)) { log().xprintf("Dropping message from %{addr} to %{addr}" " len %u: Wrong interface\n", src->sin6_addr, dst->sin6_addr, (uint32_t)g_mrd->ipktb->rlength); } return; } switch (pimmsg->type()) { case pim_msg_hello: handle_hello(src, (pim_hello_message *)g_mrd->ipktb->pheader(), g_mrd->ipktb->rlength); break; case pim_msg_joinprune: handle_joinprune(src, (pim_joinprune_message *)g_mrd->ipktb->pheader(), g_mrd->ipktb->rlength); break; case pim_msg_assert: handle_assert(src, (pim_assert_message *)g_mrd->ipktb->pheader(), g_mrd->ipktb->rlength); break; case pim_msg_bootstrap: handle_bootstrap(src, dst, (pim_bootstrap_message *)g_mrd->ipktb->pheader(), g_mrd->ipktb->rlength); break; default: m_stats.counter(AllCount, Bad)++; } } else { switch (pimmsg->type()) { case pim_msg_register: handle_register(src, dst); break; case pim_msg_register_stop: handle_register_stop(src); break; case pim_msg_bootstrap: handle_bootstrap(src, dst, (pim_bootstrap_message *)g_mrd->ipktb->pheader(), g_mrd->ipktb->rlength); break; case pim_msg_candidate_rp_adv: handle_candidate_rp_adv(src, (pim_candidate_rp_adv_message *)g_mrd->ipktb->pheader(), g_mrd->ipktb->rlength); break; default: m_stats.counter(AllCount, Bad)++; } } }
/** * Check an announce phase message and pass to appropriate message handler, * decrypting first if necessary * Returns 1 on success, 0 on error */ int handle_announce_phase(const unsigned char *packet, unsigned char *decrypted, const struct sockaddr_in *receiver, struct finfo_t *finfo, int announce, int open, int regconf) { struct uftp_h *header; const unsigned char *message; int hostidx; unsigned decryptlen, meslen; uint8_t *func; struct in_addr srcaddr; header = (struct uftp_h *)packet; hostidx = find_client(header->srcaddr); if (header->srcaddr == 0) { srcaddr = receiver->sin_addr; } else { srcaddr.s_addr = header->srcaddr; } if ((keytype != KEY_NONE) && (header->func == ENCRYPTED)) { if (hostidx == -1) { log(0, 0, "Got encrypted packet from unknown receiver %s", inet_ntoa(srcaddr)); return 0; } if (!validate_and_decrypt(packet, &decrypted, &decryptlen, mtu, keytype, groupkey, groupsalt, ivlen, hashtype, grouphmackey, hmaclen, sigtype, destlist[hostidx].encinfo->pubkey, destlist[hostidx].encinfo->pubkeylen)) { log1(0, 0, "Rejecting message from %s: decrypt/validate failed", destlist[hostidx].name); return 0; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((keytype != KEY_NONE) && (header->func == INFO_ACK)) { log1(0, 0, "Rejecting %s message from %s: not encrypted", func_name(header->func), inet_ntoa(srcaddr)); return 0; } func = (uint8_t *)&header->func; message = packet + sizeof(struct uftp_h); meslen = ntohs(header->blsize); } if (*func == ABORT) { handle_abort(message, meslen, hostidx, finfo, &srcaddr); return 1; } if (hostidx == -1) { if (open) { if (*func == REGISTER) { handle_open_register(message, meslen, finfo, receiver, &srcaddr, regconf); } else if (*func == CLIENT_KEY) { handle_open_clientkey(message, meslen, finfo, receiver, &srcaddr); } else { log1(0, 0, "Invalid function: expected " "REGISTER or CLIENT_KEY, got %s", func_name(*func)); } } else { log1(0, 0, "Host %s not in host list", inet_ntoa(srcaddr)); send_abort(finfo, "Not in host list", receiver, &srcaddr, 0, 0); } } else { switch (destlist[hostidx].status) { case DEST_MUTE: if (*func == REGISTER) { handle_register(message, meslen, finfo, receiver, &srcaddr, hostidx, regconf, open); } else if (*func == CLIENT_KEY) { handle_clientkey(message, meslen, finfo, receiver, &srcaddr, hostidx); } else { log1(0, 0, "Invalid function: expected " "REGISTER or CLIENT_KEY, got %s", func_name(*func)); } break; case DEST_REGISTERED: if (*func == INFO_ACK) { handle_info_ack(message, meslen, finfo, receiver, &srcaddr, hostidx, announce); } else if (*func == REGISTER) { handle_register(message, meslen, finfo, receiver, &srcaddr, hostidx, regconf, open); } else if (*func == CLIENT_KEY) { log(0, 0, "Received CLIENT_KEY+ from %s", destlist[hostidx].name); } else if (!announce && (*func == COMPLETE)) { handle_complete(message, meslen, finfo, hostidx); } else { log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); } break; case DEST_ACTIVE: if (*func == REGISTER) { handle_register(message, meslen, finfo, receiver, &srcaddr, hostidx, regconf, open); } else if (*func == CLIENT_KEY) { log(0, 0, "Received CLIENT_KEY+ from %s", destlist[hostidx].name); } else if (*func == INFO_ACK) { finfo->deststate[hostidx].conf_sent = 0; handle_info_ack(message, meslen, finfo, receiver, &srcaddr, hostidx, announce); } else if (!announce && (*func == COMPLETE)) { handle_complete(message, meslen, finfo, hostidx); } else { log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); } break; default: log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); break; } } return 1; }
/** * This is the main message reading loop. Messages are read, validated, * decrypted if necessary, then passed to the appropriate routine for handling. */ void mainloop() { struct uftp_h *header; unsigned char *buf, *decrypted, *message; int packetlen, listidx, hostidx, i; unsigned int decryptlen, meslen; uint8_t *func; struct sockaddr_in src; struct in_addr srcaddr; struct timeval *tv; const int bsize = 9000; // Roughly size of ethernet jumbo frame log0(0, 0, "%s", VERSIONSTR); for (i = 0; i < key_count; i++) { log(0, 0, "Loaded key with fingerprint %s", print_key_fingerprint(privkey[i])); } buf = calloc(bsize, 1); decrypted = calloc(bsize, 1); if ((buf == NULL) || (decrypted == NULL)) { syserror(0, 0, "calloc failed!"); exit(1); } header = (struct uftp_h *)buf; while (1) { tv = getrecenttimeout(); if (read_packet(listener, &src, buf, &packetlen, bsize, tv) <= 0) { continue; } if ((header->uftp_id != UFTP_VER_NUM) && (header->uftp_id != UFTP_3_0_VER)) { log(0, 0, "Invalid message from %s: not uftp packet " "or invalid version", inet_ntoa(src.sin_addr)); continue; } if (packetlen != sizeof(struct uftp_h) + ntohs(header->blsize)) { log(0, 0, "Invalid packet size from %s: got %d, expected %d", inet_ntoa(src.sin_addr), packetlen, sizeof(struct uftp_h) + ntohs(header->blsize)); continue; } if ((src.sin_addr.s_addr == out_addr.s_addr) && (src.sin_port == htons(port))) { // Packet from self -- drop continue; } if (header->func == HB_REQ) { handle_hb_request(&src, buf); continue; } if (header->func == HB_RESP) { handle_hb_response(listener, &src, buf, hb_hosts, hbhost_count, noname, privkey[0]); continue; } if (header->func == KEY_REQ) { handle_key_req(&src, buf); continue; } if (header->func == PROXY_KEY) { // Only clients handle these, so drop continue; } if ((proxy_type == SERVER_PROXY) && (down_addr.sin_addr.s_addr == INADDR_ANY)) { log(0, 0, "Rejecting message from %s: downstream address " "not established", inet_ntoa(src.sin_addr)); continue; } listidx = find_group(ntohl(header->group_id)); if (header->func == ANNOUNCE) { handle_announce(listidx, &src, buf); } else { if (listidx == -1) { continue; } if (proxy_type == SERVER_PROXY) { // Server proxies don't do anything outside of an ANNOUNCE. // Just send it on through. forward_message(listidx, &src, buf); continue; } if (header->func == ABORT) { handle_abort(listidx, &src, buf); continue; } if (!memcmp(&src, &group_list[listidx].up_addr, sizeof(src))) { // Downstream message if (header->func == KEYINFO) { handle_keyinfo(listidx, buf); } else if ((header->func == REG_CONF) && (group_list[listidx].keytype != KEY_NONE)) { handle_regconf(listidx, buf); } else { // If we don't need to process the message, don't bother // decrypting anything. Just forward it on. forward_message(listidx, &src, buf); } } else { // Upstream message // Decrypt first if necessary hostidx = find_client(listidx, header->srcaddr); if ((hostidx != -1) && (header->func == ENCRYPTED) && (group_list[listidx].keytype != KEY_NONE)) { if (!validate_and_decrypt(buf, &decrypted, &decryptlen, group_list[listidx].mtu,group_list[listidx].keytype, group_list[listidx].groupkey, group_list[listidx].groupsalt, group_list[listidx].ivlen, group_list[listidx].hashtype, group_list[listidx].grouphmackey, group_list[listidx].hmaclen, group_list[listidx].sigtype, group_list[listidx].destinfo[hostidx].pubkey, group_list[listidx].destinfo[hostidx].pubkeylen)) { log(ntohl(header->group_id), 0, "Rejecting message " "from %s: decrypt/validate failed", inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((hostidx != -1) && (group_list[listidx].keytype != KEY_NONE) && ((header->func == INFO_ACK) || (header->func == STATUS) || (header->func == COMPLETE))) { log(ntohl(header->group_id), 0, "Rejecting %s message " "from %s: not encrypted", func_name(header->func), inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)&header->func; message = buf + sizeof(struct uftp_h); meslen = ntohs(header->blsize); } if ((hostidx == -1) && (header->srcaddr == 0)) { srcaddr = src.sin_addr; } else { srcaddr.s_addr = header->srcaddr; } switch (*func) { case REGISTER: handle_register(listidx, hostidx, message, meslen, srcaddr.s_addr); break; case CLIENT_KEY: handle_clientkey(listidx, hostidx, message, meslen, srcaddr.s_addr); break; case INFO_ACK: handle_info_ack(listidx, hostidx, message, meslen); break; case STATUS: handle_status(listidx, hostidx, message, meslen); break; case COMPLETE: handle_complete(listidx, hostidx, message, meslen); break; default: forward_message(listidx, &src, buf); break; } } } } }
struct plugin *helper_get_example_plugin(void) { struct plugin *p = MALLOC(struct plugin); struct function *f = MALLOC(struct function); if (!p || !f) LOG_ERROR("[test] Failed to alloc mem for example plugin.\n"); p->key = (string) {.str = "0123456789ABCDEF", .length = sizeof("0123456789ABCDEF") - 1}; p->name = (string) {.str = "plugin name", .length = sizeof("plugin name") - 1}; p->description = (string) {.str = "plugin desc", .length = sizeof("plugin desc") - 1}; p->license = (string) {.str = "plugin license", .length = sizeof("plugin license") - 1}; p->author = (string) {.str = "plugin author", .length = sizeof("plugin author") - 1}; p->callid = 0; f->name = (string) {.str = "function name", .length = sizeof("function name") - 1}; f->description = (string) {.str = "function desc", .length = sizeof("function desc") - 1}; f->args[0] = (string) {.str = "arg 1", .length = sizeof("arg 1") - 1}; f->args[1] = (string) {.str = "arg 2", .length = sizeof("arg 2") - 1}; p->function = f; return p; } void helper_free_plugin(struct plugin *p) { FREE(p->function); FREE(p); } /* Builds a register call and executes handle_register in order * to register the plugin. */ void helper_register_plugin(struct plugin *p) { connection_request_event_info info; struct message_request *register_request; array *meta, *functions, *func1, *args; struct api_error err = ERROR_INIT; info.request.msgid = 1; register_request = &info.request; assert_non_null(register_request); info.api_error = err; info.con = CALLOC(1, struct connection); info.con->closed = true; info.con->msgid = 1; info.con->id = (uint64_t) randommod(281474976710656LL); assert_non_null(info.con); strlcpy(info.con->cc.pluginkeystring, p->key.str, p->key.length+1); connect_to_db(); assert_int_equal(0, connection_init()); /* first level arrays: * * [meta] args->obj[0] * [functions] args->obj[1] */ register_request->params.size = 2; register_request->params.obj = CALLOC(2, struct message_object); register_request->params.obj[0].type = OBJECT_TYPE_ARRAY; register_request->params.obj[1].type = OBJECT_TYPE_ARRAY; /* meta array: * * [name] * [desciption] * [author] * [license] */ meta = ®ister_request->params.obj[0].data.params; meta->size = 4; meta->obj = CALLOC(meta->size, struct message_object); meta->obj[0].type = OBJECT_TYPE_STR; meta->obj[0].data.string = cstring_copy_string(p->name.str); meta->obj[1].type = OBJECT_TYPE_STR; meta->obj[1].data.string = cstring_copy_string(p->description.str); meta->obj[2].type = OBJECT_TYPE_STR; meta->obj[2].data.string = cstring_copy_string(p->author.str); meta->obj[3].type = OBJECT_TYPE_STR; meta->obj[3].data.string = cstring_copy_string(p->license.str); functions = ®ister_request->params.obj[1].data.params; functions->size = 1; functions->obj = CALLOC(functions->size, struct message_object); functions->obj[0].type = OBJECT_TYPE_ARRAY; func1 = &functions->obj[0].data.params; func1->size = 3; func1->obj = CALLOC(3, struct message_object); func1->obj[0].type = OBJECT_TYPE_STR; func1->obj[0].data.string = cstring_copy_string(p->function->name.str); func1->obj[1].type = OBJECT_TYPE_STR; func1->obj[1].data.string = cstring_copy_string(p->function->description.str); func1->obj[2].type = OBJECT_TYPE_ARRAY; /* function arguments */ args = &func1->obj[2].data.params; args->size = 2; args->obj = CALLOC(2, struct message_object); args->obj[0].type = OBJECT_TYPE_STR; args->obj[0].data.string = cstring_copy_string(p->function->args[0].str); args->obj[1].type = OBJECT_TYPE_STR; args->obj[1].data.string = cstring_copy_string(p->function->args[1].str); /* before running function, it must be registered successfully */ info.api_error.isset = false; expect_check(__wrap_crypto_write, &deserialized, validate_register_response, NULL); info.con->refcount++; connection_hashmap_put(info.con->id, info.con); pluginkeys_hashmap_put(info.con->cc.pluginkeystring, info.con->id); assert_int_equal(0, handle_register(info.con->id, &info.request, info.con->cc.pluginkeystring, &info.api_error)); assert_false(info.api_error.isset); //hashmap_put(uint64_t, ptr_t)(connections, info.con->id, info.con); free_params(register_request->params); //FREE(args->obj); //FREE(func1->obj); //FREE(functions->obj); //FREE(meta->obj); //FREE(register_request->params.obj); } /* Builds a run request */ void helper_build_run_request(struct message_request *rr, struct plugin *plugin, message_object_type metaarraytype, size_t metasize, message_object_type metaclientidtype, message_object_type metacallidtype, message_object_type functionnametype, message_object_type argstype ) { array argsarray = ARRAY_INIT; array *meta; rr->msgid = 1; rr->params.size = 3; rr->params.obj = CALLOC(rr->params.size, struct message_object); rr->params.obj[0].type = metaarraytype; meta = &rr->params.obj[0].data.params; meta->size = metasize; meta->obj = CALLOC(meta->size, struct message_object); meta->obj[0].type = metaclientidtype; meta->obj[0].data.string = cstring_copy_string(plugin->key.str); meta->obj[1].type = metacallidtype; rr->params.obj[1].type = functionnametype; rr->params.obj[1].data.string = cstring_copy_string(plugin->function->name.str); argsarray.size = 2; argsarray.obj = CALLOC(argsarray.size, struct message_object); argsarray.obj[0].type = OBJECT_TYPE_STR; /* first argument */ argsarray.obj[0].data.string = cstring_copy_string(plugin->function->args[0].str); argsarray.obj[1].type = OBJECT_TYPE_STR; /* second argument */ argsarray.obj[1].data.string = cstring_copy_string(plugin->function->args[1].str); rr->params.obj[2].type = argstype; rr->params.obj[2].data.params = argsarray; } void helper_build_result_request(struct message_request *rr, struct plugin *plugin, message_object_type metaarraytype, size_t metasize, message_object_type metacallidtype, message_object_type argstype) { array argsarray = ARRAY_INIT; array *meta; rr->msgid = 1; rr->params.size = 2; rr->params.obj = CALLOC(rr->params.size, struct message_object); rr->params.obj[0].type = metaarraytype; meta = &rr->params.obj[0].data.params; meta->size = metasize; meta->obj = CALLOC(meta->size, struct message_object); meta->obj[0].type = metacallidtype; meta->obj[0].data.uinteger = plugin->callid; argsarray.size = 2; argsarray.obj = CALLOC(argsarray.size, struct message_object); argsarray.obj[0].type = OBJECT_TYPE_STR; /* first argument */ argsarray.obj[0].data.string = cstring_copy_string(plugin->function->args[0].str); argsarray.obj[1].type = OBJECT_TYPE_STR; /* second argument */ argsarray.obj[1].data.string = cstring_copy_string(plugin->function->args[1].str); rr->params.obj[1].type = argstype; rr->params.obj[1].data.params = argsarray; } void helper_request_set_callid(struct message_request *rr, message_object_type callidtype) { array *meta = &rr->params.obj[0].data.params; meta->obj[0].type = callidtype; } void helper_request_set_meta_size(struct message_request *rr, message_object_type metatype, uint64_t metasize) { rr->params.obj[0].type = metatype; rr->params.obj[0].data.params.size = metasize; } void helper_request_set_args_size(struct message_request *rr, message_object_type argstype, uint64_t argssize) { rr->params.obj[1].type = argstype; rr->params.obj[1].data.params.size = argssize; } void helper_request_set_function_name(struct message_request *rr, message_object_type nametype, char *name) { free_string(rr->params.obj[1].data.string); rr->params.obj[1].type = nametype; rr->params.obj[1].data.string = cstring_copy_string(name); } void helper_request_set_pluginkey_type(struct message_request *rr, message_object_type pluginkeytype, char *pluginkey) { array *meta = &rr->params.obj[0].data.params; free_string(meta->obj[0].data.string); meta->obj[0].data.string = cstring_copy_string(pluginkey); meta->obj[0].type = pluginkeytype; }
void *taim_server(void*stupid) { unsigned int addrlen; int server, client, ret, ix, yes=1; struct sockaddr_in name; struct sockaddr addr; struct hostent *gethostbyaddr(); // End of Declaration atomic_increment(); addr.sa_family = AF_INET; strcpy(addr.sa_data, "somename"); name.sin_family = AF_INET; name.sin_port = htons(19091); name.sin_addr.s_addr = INADDR_ANY; server = socket(PF_INET, SOCK_STREAM, 0); handle_register(server); setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); // setsockopt if(bind(server, (struct sockaddr*)&name, sizeof(name))<0) { printf("Could not bind to port: "); while(bind(server, (struct sockaddr*)&name, sizeof(name))<0) { printf("."); usleep(990000); fflush(0); } printf("\n"); } printf("Running on port:\t%d\n", ntohs(name.sin_port)); addrlen = sizeof(addr); getsockname(server, &addr, &addrlen); listen(server, 10); for(;;) { client = accept(server,0,0); if(client == -1) { if (g_die) { break; } continue; } handle_register(client); for(ix = 0; ix < MAX_CONNECT; ix++) { if(g_client_inuse[ix] == 0) { client_struct toPass; toPass.client = client; toPass.thread = ix; ret = pthread_create(&g_client_thread[ix], 0, client_chat, (void*)&toPass); pthread_detach(g_client_thread[ix]); break; } } handle_deregister(client); } fcntl(server,F_SETFL,O_NONBLOCK); atomic_decrement(); return 0; }