void chk_iprange(char *value, struct s_ip **base) { int32_t i = 0; char *ptr1, *ptr2, *saveptr1 = NULL; struct s_ip *fip, *lip, *cip; cs_malloc(&cip, sizeof(struct s_ip), SIGINT); fip = cip; for (ptr1=strtok_r(value, ",", &saveptr1); ptr1; ptr1=strtok_r(NULL, ",", &saveptr1)) { if (i == 0) ++i; else { cs_malloc(&cip, sizeof(struct s_ip), SIGINT); lip->next = cip; } if( (ptr2=strchr(trim(ptr1), '-')) ) { *ptr2++ ='\0'; cs_inet_addr(trim(ptr1), &cip->ip[0]); cs_inet_addr(trim(ptr2), &cip->ip[1]); } else { cs_inet_addr(ptr1, &cip->ip[0]); IP_ASSIGN(cip->ip[1], cip->ip[0]); } lip = cip; } lip = *base; *base = fip; clear_sip(&lip); }
void module_monitor(struct s_module *ph){ static PTAB ptab; //since there is always only 1 monitor running, this is threadsafe ptab.ports[0].s_port = cfg.mon_port; ph->ptab = &ptab; ph->ptab->nports = 1; ph->desc = "monitor"; ph->type=MOD_CONN_UDP; IP_ASSIGN(ph->s_ip, cfg.mon_srvip); ph->s_handler = monitor_server; ph->recv = monitor_recv; // ph->send_dcw=NULL; }
/* Resolves the ip of the hostname of the specified account and saves it in account->dynip. If the hostname is not configured, the ip is set to 0. */ static void cs_user_resolve(struct s_auth *account) { if (account->dyndns) { IN_ADDR_T lastip; IP_ASSIGN(lastip, account->dynip); cs_resolve(account->dyndns, &account->dynip, NULL, NULL); if (!IP_EQUAL(lastip, account->dynip)) { cs_log("%s: resolved ip=%s", account->dyndns, cs_inet_ntoa(account->dynip)); } } else { set_null_ip(&account->dynip); } }
struct s_client *create_client(IN_ADDR_T ip) { struct s_client *cl; if(!cs_malloc(&cl, sizeof(struct s_client))) { cs_log("max connections reached (out of memory) -> reject client %s", IP_ISSET(ip) ? cs_inet_ntoa(ip) : "with null address"); return NULL; } //client part IP_ASSIGN(cl->ip, ip); cl->account = first_client->account; //master part pthread_mutex_init(&cl->thread_lock, NULL); cl->login = cl->last = time(NULL); cl->tid = (uint32_t)(uintptr_t)cl; // Use pointer adress of client as threadid (for monitor and log) //Now add new client to the list: struct s_client *last; cs_writelock(&clientlist_lock); if(sizeof(uintptr_t) > 4) // 64bit systems can have collisions because of the cast so lets check if there are some { int8_t found; do { found = 0; for(last = first_client; last; last = last->next) { if(last->tid == cl->tid) { found = 1; break; } } if(found || cl->tid == 0) { cl->tid = (uint32_t)rand(); } } while(found || cl->tid == 0); } for(last = first_client; last->next != NULL; last = last->next) { ; } //ends with cl on last client last->next = cl; int32_t bucket = (uintptr_t)cl / 16 % CS_CLIENT_HASHBUCKETS; cl->nexthashed = first_client_hashed[bucket]; first_client_hashed[bucket] = cl; #ifdef MODULE_GBOX cl->gbox_peer_id = 0; #endif cs_writeunlock(&clientlist_lock); return cl; }
void module_radegast(struct s_module *ph) { static PTAB ptab; //since there is always only 1 radegast server running, this is threadsafe ptab.ports[0].s_port = cfg.rad_port; ph->ptab = &ptab; ph->ptab->nports = 1; ph->desc="radegast"; ph->type=MOD_CONN_TCP; ph->listenertype = LIS_RADEGAST; IP_ASSIGN(ph->s_ip, cfg.rad_srvip); ph->s_handler=radegast_server; ph->s_init=radegast_server_init; ph->recv=radegast_recv; ph->send_dcw=radegast_send_dcw; ph->c_init=radegast_cli_init; ph->c_recv_chk=radegast_recv_chk; ph->c_send_ecm=radegast_send_ecm; ph->num=R_RADEGAST; }
void module_radegast(struct s_module *ph) { ph->ptab.nports = 1; ph->ptab.ports[0].s_port = cfg.rad_port; ph->desc = "radegast"; ph->type = MOD_CONN_TCP; ph->large_ecm_support = 1; ph->listenertype = LIS_RADEGAST; IP_ASSIGN(ph->s_ip, cfg.rad_srvip); ph->s_handler = radegast_server; ph->s_init = radegast_server_init; ph->c_idle = radegast_idle; ph->recv = radegast_recv; ph->send_dcw = radegast_send_dcw; ph->c_init = radegast_cli_init; ph->c_recv_chk = radegast_recv_chk; ph->c_send_ecm = radegast_send_ecm; ph->num = R_RADEGAST; }
struct s_client *create_client(IN_ADDR_T ip) { struct s_client *cl; if(!cs_malloc(&cl, sizeof(struct s_client))) { cs_log("max connections reached (out of memory) -> reject client %s", IP_ISSET(ip) ? cs_inet_ntoa(ip) : "with null address"); return NULL; } //client part IP_ASSIGN(cl->ip, ip); cl->account = first_client->account; //master part SAFE_MUTEX_INIT(&cl->thread_lock, NULL); cl->login = cl->last = time(NULL); cl->tid = (uint32_t)rand(); //Now add new client to the list: struct s_client *last; cs_writelock(__func__, &clientlist_lock); for(last = first_client; last && last->next; last = last->next) { ; } //ends with cl on last client if (last) last->next = cl; int32_t bucket = (uintptr_t)cl / 16 % CS_CLIENT_HASHBUCKETS; cl->nexthashed = first_client_hashed[bucket]; first_client_hashed[bucket] = cl; cs_writeunlock(__func__, &clientlist_lock); return cl; }
/************************************************************************************************************************ * client functions *************************************************************************************************************************/ int pandora_client_init(struct s_client *cl) { static struct sockaddr_in loc_sa; int16_t p_proto; char ptxt[16]; struct s_reader *rdr = cl->reader; uchar md5tmp[MD5_DIGEST_LENGTH]; cl->pfd = 0; if (rdr->r_port <= 0) { cs_log("invalid port %d for server %s", rdr->r_port, rdr->device); return (1); } p_proto = IPPROTO_UDP; set_null_ip(&cl->ip); memset((char *) &loc_sa, 0, sizeof(loc_sa)); loc_sa.sin_family = AF_INET; if (IP_ISSET(cfg.srvip)) IP_ASSIGN(SIN_GET_ADDR(loc_sa), cfg.srvip); else loc_sa.sin_addr.s_addr = INADDR_ANY; loc_sa.sin_port = htons(rdr->l_port); if ((cl->udp_fd = socket(PF_INET, SOCK_DGRAM, p_proto)) < 0) { cs_log("Socket creation failed (errno=%d)", errno); return 1; } int32_t opt = 1; setsockopt(cl->udp_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); #ifdef SO_REUSEPORT setsockopt(cl->udp_fd, SOL_SOCKET, SO_REUSEPORT, (void *)&opt, sizeof(opt)); #endif set_socket_priority(cl->udp_fd, cfg.netprio); if (rdr->l_port > 0) { if (bind(cl->udp_fd, (struct sockaddr *) &loc_sa, sizeof(loc_sa)) < 0) { cs_log("bind failed (errno=%d)", errno); close(cl->udp_fd); return (1); } snprintf(ptxt, sizeof(ptxt), ", port=%d", rdr->l_port); } else ptxt[0] = '\0'; memcpy(cl->pand_md5_key, MD5((uchar*)rdr->r_pwd, strlen(rdr->r_pwd), md5tmp), 16); cl->crypted = 1; //cl->grp = 0xFFFFFFFF; //rdr->caid[0] = rdr->ctab.caid[0]; cl->pand_send_ecm = rdr->pand_send_ecm; memset((char *) &cl->udp_sa, 0, sizeof(cl->udp_sa)); #ifdef IPV6SUPPORT ((struct sockaddr_in *)(&cl->udp_sa))->sin_family = AF_INET; ((struct sockaddr_in *)(&cl->udp_sa))->sin_port = htons((u_short) rdr->r_port); #else cl->udp_sa.sin_family = AF_INET; cl->udp_sa.sin_port = htons((u_short) rdr->r_port); #endif cs_log("proxy %s:%d pandora %s (%s)", rdr->device, rdr->r_port, rdr->pand_send_ecm?"with ECM support":"", ptxt ); cl->pfd = cl->udp_fd; //fcntl(cl->udp_fd, F_SETFL, fcntl(cl->udp_fd, F_GETFL, 0) | O_NONBLOCK); //!!!!! return (0); }