int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci)) { int i; if (!client) client_alloc(); again: for (i = 0; i < client_size; i++) { if (client[i].fd == -1) { client[i].workfn = workfn; if (deadfn) client[i].deadfn = deadfn; else client[i].deadfn = client_dead; client[i].fd = fd; pollfd[i].fd = fd; pollfd[i].events = POLLIN; if (i > client_maxi) client_maxi = i; return i; } } client_alloc(); goto again; }
static void server_on_connection(uv_stream_t *handle, int status) { server_t *server = handle->data; // allocate client client_t *client = client_alloc(server->sizeof_client); // setup client client->server = server; // accept client // TODO: report errors uv_tcp_init(server->handle.loop, &client->handle); client->handle.data = client; // TODO: EMFILE trick! // https://github.com/joyent/libuv/blob/master/src/unix/ev/ev.3#L1812-1816 if (uv_accept((uv_stream_t *)&server->handle, (uv_stream_t *)&client->handle)) { // accept failed? report error client->server->on_event(server, EVT_ERROR, uv_last_error(uv_default_loop()).code, NULL); exit(-2); } // fire 'open' event client->server->on_event(client, EVT_CLI_OPEN, 0, NULL); // start reading client uv_read_start((uv_stream_t *)&client->handle, buf_alloc, client_on_read); }
int client_add(int fd, uid_t uid) { int i; if (client == NULL) /* first time we're called */ client_alloc(); again: for (i = 0; i < client_size; i++) { if (client[i].fd == -1) { /* find an available entry */ client[i].fd = fd; client[i].uid = uid; return(i); /* return index in client[] array */ } } /* client array full, time to realloc for more */ client_alloc(); goto again; /* and search again (will work this time) */ }
int client_add(int fd, uid_t uid) { int i; if (client == NULL) { client_alloc(); } again: for (i = 0; i < client_size; i++) { if (client[i].fd == -1) { client[i].fd = fd; client[i].uid = uid; return i; } } client_alloc(); goto again; }
void scan_windows(void) { const int screens_len = xcb_setup_roots_length(xcb_get_setup(wm_conf.connection)); int screen_idx; xcb_window_t root_wins[screens_len]; xcb_query_tree_cookie_t root_tree_cookies[screens_len]; /* request window trees for the root window of each screen */ for (screen_idx = 0; screen_idx < screens_len; ++screen_idx) { xcb_screen_t *screen = xcb_aux_get_screen(wm_conf.connection, screen_idx); root_wins[screen_idx] = screen->root; root_tree_cookies[screen_idx] = xcb_query_tree_unchecked(wm_conf.connection, root_wins[screen_idx]); } xcb_query_tree_reply_t *root_tree_replies[screens_len]; xcb_window_t *wins; int wins_len; /* collect replies */ for (screen_idx = 0; screen_idx < screens_len; ++screen_idx) { root_tree_replies[screen_idx] = xcb_query_tree_reply(wm_conf.connection, root_tree_cookies[screen_idx], NULL); wins = xcb_query_tree_children(root_tree_replies[screen_idx]); if (!wins) fprintf(stderr, "failed to get child tree for window %u\n", root_wins[screen_idx]); wins_len = xcb_query_tree_children_length(root_tree_replies[screen_idx]); fprintf(stderr, "root window %u has %d children\n", root_wins[screen_idx], wins_len); fprintf(stderr, "examining children\n"); xcb_window_t child_win; int i; for (i = 0; i < wins_len; ++i) { child_win = wins[i]; fprintf(stderr, " child window %u\n", child_win); client_t *client = find_client(child_win); if (!client) { client = client_init(client_alloc()); client->window = child_win; sglib_client_t_add(&client_list, client); } read_client_geometry(client); } } for (screen_idx = 0; screen_idx < screens_len; ++screen_idx) free(root_tree_replies[screen_idx]); }
struct srv_client* srv_ctable_connect_direct_handler(srv_common_t *srv, srv_msg_t *m, seL4_CPtr liveness, int* _errno) { assert(srv && srv->magic == SRV_MAGIC && m); /* Check that the liveness cap passed in correctly. */ if(!srv_check_dispatch_caps(m, 0x00000000, 1)) { SET_ERRNO_PTR(_errno, EINVALIDPARAM); return NULL; } int error = ENOMEM; /* Copyout the liveness cap, create session cap cslot. Do not printf before the copyout. */ seL4_CPtr livenessCP = rpc_copyout_cptr(liveness); if (!liveness || !livenessCP) { goto error0; } /* Allocate the client structure. */ struct srv_client *c = client_alloc(&srv->clientTable, livenessCP); if (!c) { goto error1; } dprintf("Adding new %s client cID = %d. Hi! (:D)\n", srv->config.serverName, c->cID); assert(c->session); /* Authenticate the client to the process server, using its liveness cap. */ error = proc_watch_client(c->liveness, srv->notifyClientFaultDeathAsyncEP, &c->deathID); if (error != ESUCCESS) { goto error2; } SET_ERRNO_PTR(_errno, ESUCCESS); return c; /* Exit stack. */ error2: client_queue_delete(&srv->clientTable, c->cID); client_table_postaction(&srv->clientTable); error1: seL4_CNode_Delete(REFOS_CSPACE, livenessCP, REFOS_CDEPTH); csfree(livenessCP); error0: SET_ERRNO_PTR(_errno, error); return NULL; }
client_t *manage_window(xcb_window_t window) { client_t *client = client_init(client_alloc()); client->window = window; sglib_client_t_add(&client_list, client); read_client_geometry(client); client->border_width = 0; update_client_geometry(client); xcb_map_window(wm_conf.connection, client->window); run_arrange_hook(); return client; }
static void accept_func( void* _server, int events ) { SysChannel server = _server; SysChannel handler; Client client; printf( "connection accepted for server channel, getting handler socket\n" ); handler = sys_channel_create_tcp_handler( server ); client = client_alloc( handler ); printf( "got one. created client %p\n", client ); events=events; sys_channel_on( handler, SYS_EVENT_READ, client_handler, client ); }
network_client * network_client_new(uint32_t size, network_client_ops *ops, uint32_t factory, void *io) { init_parm parm; if (size < sizeof(network_client)) { unix_sock_close((int32_t)io); return NULL; } parm.opts = ops; parm.io = io; parm.factory = factory; return (network_client*)client_alloc( size, &client_ops_impl,&parm,__FUNCTION__); }
static void peerip_clients_close(void) { struct client_t *c; c = client_alloc(); if (!c) { hlog(LOG_ERR, "peerip_clients_close: client_alloc returned NULL"); abort(); } c->fd = -2; // Magic FD to close them all c->state = CSTATE_COREPEER; sprintf(c->filter_s, "peerip_clients_close"); // debugging if (pass_client_to_worker(worker_threads, c)) { hlog(LOG_ERR, "Failed to pass magic peerip_clients_close message pseudoclient to worker"); client_free(c); } }
int client_add(int fd, const struct booth_transport *tpt, void (*workfn)(int ci), void (*deadfn)(int ci)) { int i; struct client *c; if (client_size - 1 <= client_maxi ) { client_alloc(); } for (i = 0; i < client_size; i++) { c = clients + i; if (c->fd != -1) continue; c->workfn = workfn; if (deadfn) c->deadfn = deadfn; else c->deadfn = client_dead; c->transport = tpt; c->fd = fd; c->msg = NULL; c->offset = 0; pollfds[i].fd = fd; pollfds[i].events = POLLIN; if (i > client_maxi) client_maxi = i; return i; } assert(!"no client"); }
void server_accept_client(struct evconnlistener *listener, evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr) { int port = ntohs(((struct sockaddr_in*)addr)->sin_port); sds ip = sdsnew(inet_ntoa(((struct sockaddr_in*)addr)->sin_addr)); server.client_connected++; log_info("Accepted client socket from %s:%d, current[%d], max[%d], total[%"PRIu64"]", ip, port, server.client_current + 1, server.client_max, server.client_connected); if(server.client_current >= server.client_max) { ssize_t wl; log_warn("Reached max connection: %d, client will be closed.", server.client_current + 1); sds msg = sdscatprintf(sdsempty(), "%s 1%sMax connection error.", ZR_CMD_REP_ERR, ZR_MSG_NL); wl = write(sock, msg, sdslen(msg)); sdsfree(msg); close(sock); return; } //struct client *c = client_alloc(sock, (struct sockaddr_in*)addr); client_alloc(sock, (struct sockaddr_in*)addr); }
static REQUEST *request_setup(FILE *fp) { REQUEST *request; /* * Create and initialize the new request. */ request = request_alloc(NULL); request->packet = rad_alloc(request, 0); if (!request->packet) { ERROR("No memory"); request_free(&request); return NULL; } request->reply = rad_alloc(request, 0); if (!request->reply) { ERROR("No memory"); request_free(&request); return NULL; } request->listener = listen_alloc(request); request->client = client_alloc(request); request->number = 0; request->master_state = REQUEST_ACTIVE; request->child_state = REQUEST_ACTIVE; request->handle = NULL; request->server = talloc_strdup(request, "default"); request->root = &mainconfig; /* * Read packet from fp */ request->packet->vps = readvp2(request->packet, fp, &filedone, "radiusd:"); if (!request->packet->vps) { talloc_free(request); return NULL; } /* * FIXME: set IPs, etc. */ request->packet->code = PW_CODE_AUTHENTICATION_REQUEST; request->packet->src_ipaddr.af = AF_INET; request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->src_port = 18120; request->packet->dst_ipaddr.af = AF_INET; request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->dst_port = 1812; /* * Build the reply template from the request. */ request->reply->sockfd = request->packet->sockfd; request->reply->dst_ipaddr = request->packet->src_ipaddr; request->reply->src_ipaddr = request->packet->dst_ipaddr; request->reply->dst_port = request->packet->src_port; request->reply->src_port = request->packet->dst_port; request->reply->id = request->packet->id; request->reply->code = 0; /* UNKNOWN code */ memcpy(request->reply->vector, request->packet->vector, sizeof(request->reply->vector)); request->reply->vps = NULL; request->reply->data = NULL; request->reply->data_len = 0; /* * Debugging */ request->options = debug_flag; request->radlog = radlog_request; request->username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY); request->password = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY); return request; }
int make_uplink(struct uplink_config_t *l) { int fd, i, addrc, arg; int uplink_index; union sockaddr_u sa; /* large enough for also IPv6 address */ socklen_t addr_len; struct addrinfo *ai, *a, *ap[21]; struct addrinfo req; char *addr_s = NULL; int port; struct sockaddr *srcaddr; socklen_t srcaddr_len; memset(&req, 0, sizeof(req)); req.ai_family = 0; req.ai_socktype = SOCK_STREAM; req.ai_protocol = IPPROTO_TCP; req.ai_flags = AI_ADDRCONFIG; ai = NULL; #ifdef USE_SSL /* SSL requires both a cert and a key, or none at all */ if ((l->certfile && !l->keyfile) || (l->keyfile && !l->certfile)) { hlog(LOG_ERR, "Uplink %s: Only one of sslkey and sslcert defined - both needed for SSL authentication", l->name); return -2; } /* todo: allow triggering SSL without client auth */ if (l->keyfile && l->certfile) { if (!l->ssl) { if (config_uplink_ssl_setup(l)) { hlog(LOG_ERR, "Uplink '%s': SSL setup failed", l->name); return -2; } } } #endif /* find a free uplink slot */ for (uplink_index = 0; uplink_index < MAX_UPLINKS; uplink_index++) { if (!uplink_client[uplink_index]) break; } if (uplink_index == MAX_UPLINKS) { hlog(LOG_ERR, "Uplink %s: No available uplink slots, %d used", l->name, MAX_UPLINKS); return -2; } if (strcasecmp(l->proto, "tcp") == 0) { // well, do nothing for now. } else if (strcasecmp(l->proto, "udp") == 0) { req.ai_socktype = SOCK_DGRAM; req.ai_protocol = IPPROTO_UDP; #ifdef USE_SCTP } else if (strcasecmp(l->proto, "sctp") == 0) { req.ai_socktype = SOCK_STREAM; req.ai_protocol = IPPROTO_SCTP; #endif } else { hlog(LOG_ERR, "Uplink %s: Unsupported protocol '%s'\n", l->name, l->proto); return -2; } port = atoi(l->port); if (port < 1 || port > 65535) { hlog(LOG_ERR, "Uplink %s: unsupported port number '%s'\n", l->name, l->port); return -2; } l->state = UPLINK_ST_CONNECTING; i = getaddrinfo(l->host, l->port, &req, &ai); if (i != 0) { hlog(LOG_INFO, "Uplink %s: address resolving failure of '%s' '%s': %s", l->name, l->host, l->port, gai_strerror(i)); l->state = UPLINK_ST_NOT_LINKED; return -2; } /* Count the amount of addresses in response */ addrc = 0; for (a = ai; a && addrc < 20 ; a = a->ai_next, ++addrc) { ap[addrc] = a; /* Up to 20 first addresses */ } ap[addrc] = NULL; if (addrc == 0) { hlog(LOG_INFO, "Uplink %s: address resolving of '%s' '%s': returned 0 addresses", l->name, l->host, l->port); l->state = UPLINK_ST_NOT_LINKED; return -2; } /* Pick random address to start from */ i = random() % addrc; /* Then lets try making socket and connection in address order */ /* TODO: BUG: If the TCP connection succeeds, but the server rejects our * login due to a bad source address (like, IPv4 would be allowed but our * IPv6 address is not in the server's ACL), this currently does not switch * to the next destination address. * Instead it'll wait for the retry timer and then try a random * destination address, and eventually succeed (unless very unlucky). */ fd = -1; while ((a = ap[i])) { ap[i] = NULL; addr_s = strsockaddr(a->ai_addr, a->ai_addrlen); hlog(LOG_INFO, "Uplink %s: Connecting to %s:%s (%s) [link %d, addr %d/%d]", l->name, l->host, l->port, addr_s, uplink_index, i+1, addrc); i++; if (i == addrc) i = 0; if ((fd = socket(a->ai_family, a->ai_socktype, a->ai_protocol)) < 0) { hlog(LOG_CRIT, "Uplink %s: socket(): %s\n", l->name, strerror(errno)); hfree(addr_s); continue; } arg = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, sizeof(arg))) hlog(LOG_ERR, "Uplink %s: Failed to set SO_REUSEADDR on new socket: %s", l->name, strerror(errno)); /* bind source address */ srcaddr_len = 0; if (a->ai_family == AF_INET && uplink_bind_v4_len != 0) { srcaddr = (struct sockaddr *)&uplink_bind_v4; srcaddr_len = uplink_bind_v4_len; } else if (a->ai_family == AF_INET6 && uplink_bind_v6_len != 0) { srcaddr = (struct sockaddr *)&uplink_bind_v6; srcaddr_len = uplink_bind_v6_len; } if (srcaddr_len) { if (bind(fd, srcaddr, srcaddr_len)) { char *s = strsockaddr(srcaddr, srcaddr_len); hlog(LOG_ERR, "Uplink %s: Failed to bind source address '%s': %s", l->name, s, strerror(errno)); hfree(s); goto connerr; } } /* set non-blocking mode at this point, so that we can make a * non-blocking connect() with a short timeout */ if (fcntl(fd, F_SETFL, O_NONBLOCK)) { hlog(LOG_CRIT, "Uplink %s: Failed to set non-blocking mode on new socket: %s", l->name, strerror(errno)); goto connerr; } /* Use TCP_NODELAY for APRS-IS sockets. High delays can cause packets getting past * the dupe filters. */ #ifdef TCP_NODELAY if (a->ai_protocol == IPPROTO_TCP) { int arg = 1; if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&arg, sizeof(arg))) hlog(LOG_ERR, "Uplink %s: %s: setsockopt(TCP_NODELAY, %d) failed: %s", l->name, addr_s, arg, strerror(errno)); } #endif if (connect(fd, a->ai_addr, a->ai_addrlen) && errno != EINPROGRESS) { hlog(LOG_ERR, "Uplink %s: connect(%s) failed: %s", l->name, addr_s, strerror(errno)); goto connerr; } /* Only wait a few seconds for the connection to be created. * If the connection setup is very slow, it is unlikely to * perform well enough anyway. */ struct pollfd connect_fd; connect_fd.fd = fd; connect_fd.events = POLLOUT; connect_fd.revents = 0; int r = poll(&connect_fd, 1, 3000); hlog(LOG_DEBUG, "Uplink %s: poll after connect returned %d, revents %d", l->name, r, connect_fd.revents); if (r < 0) { hlog(LOG_ERR, "Uplink %s: connect to %s: poll failed: %s", l->name, addr_s, strerror(errno)); goto connerr; } if (r < 1) { hlog(LOG_ERR, "Uplink %s: connect to %s timed out", l->name, addr_s); goto connerr; } socklen_t optlen = sizeof(arg); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&arg, &optlen) == -1) { hlog(LOG_ERR, "Uplink %s: getsockopt() after connect failed: %s", l->name, strerror(errno)); goto connerr; } else if (arg == 0) { /* Successful connect! */ hlog(LOG_DEBUG, "Uplink %s: successful connect", l->name); break; } hlog(LOG_ERR, "Uplink %s: connect to %s failed: %s", l->name, addr_s, strerror(arg)); connerr: close(fd); fd = -1; hfree(addr_s); } freeaddrinfo(ai); /* Not needed anymore.. */ if (fd < 0) { l->state = UPLINK_ST_NOT_LINKED; return -3; /* No successfull connection at any address.. */ } struct client_t *c = client_alloc(); if (!c) { hlog(LOG_ERR, "Uplink %s: client_alloc() failed, too many clients", l->name); close(fd); l->state = UPLINK_ST_NOT_LINKED; return -3; /* No successfull connection at any address.. */ } l->client_ptr = (void *)c; c->uplink_index = uplink_index; c->fd = fd; c->addr = sa; c->ai_protocol = req.ai_protocol; c->state = CSTATE_INIT; /* use the default login handler */ c->handler_line_in = &uplink_login_handler; c->flags = l->client_flags; c->keepalive = tick; c->last_read = tick; c->connect_time = now; strncpy(c->username, l->name, sizeof(c->username)); c->username[sizeof(c->username)-1] = 0; c->username_len = strlen(c->username); /* These peer/sock name calls can not fail -- or the socket closed on us in which case it gets abandoned a bit further below. */ addr_len = sizeof(sa); getpeername(fd, (struct sockaddr *)&sa, &addr_len); //s = strsockaddr( &sa.sa, addr_len ); /* server side address */ strncpy(c->addr_rem, addr_s, sizeof(c->addr_rem)); c->addr_rem[sizeof(c->addr_rem)-1] = 0; hfree(addr_s); /* hex format of client's IP address + port */ char *s = hexsockaddr( &sa.sa, addr_len ); strncpy(c->addr_hex, s, sizeof(c->addr_hex)); c->addr_hex[sizeof(c->addr_hex)-1] = 0; hfree(s); addr_len = sizeof(sa); getsockname(fd, (struct sockaddr *)&sa, &addr_len); s = strsockaddr( &sa.sa, addr_len ); /* client side address */ strncpy(c->addr_loc, s, sizeof(c->addr_loc)); c->addr_loc[sizeof(c->addr_loc)-1] = 0; hfree(s); hlog(LOG_INFO, "Uplink %s: %s: Connection established on fd %d using source address %s", l->name, c->addr_rem, c->fd, c->addr_loc); if (set_client_sockopt(c) < 0) goto err; uplink_client[uplink_index] = c; l->state = UPLINK_ST_CONNECTED; /* set up SSL if necessary */ #ifdef USE_SSL if (l->ssl) { if (ssl_create_connection(l->ssl, c, 1)) goto err; } #endif /* Push it on the first worker, which ever it is.. */ if (pass_client_to_worker(worker_threads, c)) goto err; if ((i = pthread_mutex_lock(& uplink_connects.mutex ))) hlog(LOG_ERR, "make_uplink: could not lock uplink_connects: %s", strerror(i)); ++ uplink_connects.gauge; ++ uplink_connects.counter; ++ uplink_connects.refcount; /* <-- that does not get decremented at any time.. */ if ((i = pthread_mutex_unlock(& uplink_connects.mutex ))) hlog(LOG_ERR, "make_uplink: could not unlock uplink_connects: %s", strerror(i)); c->portaccount = & uplink_connects; /* calculate traffic bytes/packets */ return 0; err: client_free(c); uplink_client[uplink_index] = NULL; l->state = UPLINK_ST_NOT_LINKED; return -1; }
struct client_t *accept_client_for_listener(struct listen_t *l, int fd, char *addr_s, union sockaddr_u *sa, unsigned addr_len) { struct client_t *c; char *s; int i; union sockaddr_u sa_loc; /* local address */ socklen_t addr_len_loc = sizeof(sa_loc); c = client_alloc(); if (!c) return NULL; c->fd = fd; c->listener_id = l->listener_id; c->addr = *sa; c->ai_protocol = l->ai_protocol; c->portnum = l->portnum; c->hidden = l->hidden; c->flags = l->client_flags; c->udpclient = client_udp_find(udpclients, sa->sa.sa_family, l->portnum); c->portaccount = l->portaccount; c->last_read = tick; /* not simulated time */ inbound_connects_account(1, c->portaccount); /* account all ports + port-specifics */ /* text format of client's IP address + port */ strncpy(c->addr_rem, addr_s, sizeof(c->addr_rem)); c->addr_rem[sizeof(c->addr_rem)-1] = 0; /* hex format of client's IP address + port */ s = hexsockaddr( &sa->sa, addr_len ); strncpy(c->addr_hex, s, sizeof(c->addr_hex)); c->addr_hex[sizeof(c->addr_hex)-1] = 0; hfree(s); /* text format of servers' connected IP address + port */ if (getsockname(fd, &sa_loc.sa, &addr_len_loc) == 0) { /* Fails very rarely.. */ if (addr_len_loc > sizeof(sa_loc)) hlog(LOG_ERR, "accept_client_for_listener: getsockname for client %s truncated local address of %d to %d bytes", c->addr_rem, addr_len_loc, sizeof(sa_loc)); /* present my socket end address as a malloced string... */ s = strsockaddr( &sa_loc.sa, addr_len_loc ); } else { s = hstrdup( l->addr_s ); /* Server's bound IP address */ hlog(LOG_ERR, "accept_client_for_listener: getsockname for client %s failed: %s (using '%s' instead)", c->addr_rem, strerror(errno), s); } strncpy(c->addr_loc, s, sizeof(c->addr_loc)); c->addr_loc[sizeof(c->addr_loc)-1] = 0; hfree(s); /* apply predefined filters */ for (i = 0; i < (sizeof(l->filters)/sizeof(l->filters[0])); ++i) { if (l->filters[i]) { if (filter_parse(c, l->filters[i], 0) < 0) { /* system filters */ hlog(LOG_ERR, "Bad system filter definition: %s", l->filters[i]); } } } if (l->filter_s) { strncpy(c->filter_s, l->filter_s, sizeof(c->filter_s)); c->filter_s[FILTER_S_SIZE-1] = 0; } return c; }
static REQUEST *request_setup(FILE *fp) { VALUE_PAIR *vp; REQUEST *request; vp_cursor_t cursor; /* * Create and initialize the new request. */ request = request_alloc(NULL); request->packet = rad_alloc(request, false); if (!request->packet) { ERROR("No memory"); talloc_free(request); return NULL; } request->reply = rad_alloc(request, false); if (!request->reply) { ERROR("No memory"); talloc_free(request); return NULL; } request->listener = listen_alloc(request); request->client = client_alloc(request); request->number = 0; request->master_state = REQUEST_ACTIVE; request->child_state = REQUEST_RUNNING; request->handle = NULL; request->server = talloc_typed_strdup(request, "default"); request->root = &main_config; /* * Read packet from fp */ if (readvp2(request->packet, &request->packet->vps, fp, &filedone) < 0) { fr_perror("unittest"); talloc_free(request); return NULL; } /* * Set the defaults for IPs, etc. */ request->packet->code = PW_CODE_ACCESS_REQUEST; request->packet->src_ipaddr.af = AF_INET; request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->src_port = 18120; request->packet->dst_ipaddr.af = AF_INET; request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->dst_port = 1812; /* * Copied from radclient */ #if 1 /* * Fix up Digest-Attributes issues */ for (vp = fr_cursor_init(&cursor, &request->packet->vps); vp; vp = fr_cursor_next(&cursor)) { /* * Double quoted strings get marked up as xlat expansions, * but we don't support that here. */ if (vp->type == VT_XLAT) { vp->vp_strvalue = vp->value.xlat; vp->value.xlat = NULL; vp->type = VT_DATA; } if (!vp->da->vendor) switch (vp->da->attr) { default: break; /* * Allow it to set the packet type in * the attributes read from the file. */ case PW_PACKET_TYPE: request->packet->code = vp->vp_integer; break; case PW_PACKET_DST_PORT: request->packet->dst_port = (vp->vp_integer & 0xffff); break; case PW_PACKET_DST_IP_ADDRESS: request->packet->dst_ipaddr.af = AF_INET; request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; break; case PW_PACKET_DST_IPV6_ADDRESS: request->packet->dst_ipaddr.af = AF_INET6; request->packet->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr; break; case PW_PACKET_SRC_PORT: request->packet->src_port = (vp->vp_integer & 0xffff); break; case PW_PACKET_SRC_IP_ADDRESS: request->packet->src_ipaddr.af = AF_INET; request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; break; case PW_PACKET_SRC_IPV6_ADDRESS: request->packet->src_ipaddr.af = AF_INET6; request->packet->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr; break; case PW_CHAP_PASSWORD: { int i, already_hex = 0; /* * If it's 17 octets, it *might* be already encoded. * Or, it might just be a 17-character password (maybe UTF-8) * Check it for non-printable characters. The odds of ALL * of the characters being 32..255 is (1-7/8)^17, or (1/8)^17, * or 1/(2^51), which is pretty much zero. */ if (vp->length == 17) { for (i = 0; i < 17; i++) { if (vp->vp_octets[i] < 32) { already_hex = 1; break; } } } /* * Allow the user to specify ASCII or hex CHAP-Password */ if (!already_hex) { uint8_t *p; size_t len, len2; len = len2 = vp->length; if (len2 < 17) len2 = 17; p = talloc_zero_array(vp, uint8_t, len2); memcpy(p, vp->vp_strvalue, len); rad_chap_encode(request->packet, p, fr_rand() & 0xff, vp); vp->vp_octets = p; vp->length = 17; } } break; case PW_DIGEST_REALM: case PW_DIGEST_NONCE: case PW_DIGEST_METHOD: case PW_DIGEST_URI: case PW_DIGEST_QOP: case PW_DIGEST_ALGORITHM: case PW_DIGEST_BODY_DIGEST: case PW_DIGEST_CNONCE: case PW_DIGEST_NONCE_COUNT: case PW_DIGEST_USER_NAME: /* overlapping! */ { DICT_ATTR const *da; uint8_t *p, *q; p = talloc_array(vp, uint8_t, vp->length + 2); memcpy(p + 2, vp->vp_octets, vp->length); p[0] = vp->da->attr - PW_DIGEST_REALM + 1; vp->length += 2; p[1] = vp->length; da = dict_attrbyvalue(PW_DIGEST_ATTRIBUTES, 0); rad_assert(da != NULL); vp->da = da; /* * Re-do pairmemsteal ourselves, * because we play games with * vp->da, and pairmemsteal goes * to GREAT lengths to sanitize * and fix and change and * double-check the various * fields. */ memcpy(&q, &vp->vp_octets, sizeof(q)); talloc_free(q); vp->vp_octets = talloc_steal(vp, p); vp->type = VT_DATA; VERIFY_VP(vp); } break; } } /* loop over the VP's we read in */ #endif if (debug_flag) { for (vp = fr_cursor_init(&cursor, &request->packet->vps); vp; vp = fr_cursor_next(&cursor)) { /* * Take this opportunity to verify all the VALUE_PAIRs are still valid. */ if (!talloc_get_type(vp, VALUE_PAIR)) { ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp)); fr_log_talloc_report(vp); rad_assert(0); } vp_print(fr_log_fp, vp); } fflush(fr_log_fp); } /* * FIXME: set IPs, etc. */ request->packet->code = PW_CODE_ACCESS_REQUEST; request->packet->src_ipaddr.af = AF_INET; request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->src_port = 18120; request->packet->dst_ipaddr.af = AF_INET; request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->dst_port = 1812; /* * Build the reply template from the request. */ request->reply->sockfd = request->packet->sockfd; request->reply->dst_ipaddr = request->packet->src_ipaddr; request->reply->src_ipaddr = request->packet->dst_ipaddr; request->reply->dst_port = request->packet->src_port; request->reply->src_port = request->packet->dst_port; request->reply->id = request->packet->id; request->reply->code = 0; /* UNKNOWN code */ memcpy(request->reply->vector, request->packet->vector, sizeof(request->reply->vector)); request->reply->vps = NULL; request->reply->data = NULL; request->reply->data_len = 0; /* * Debugging */ request->log.lvl = debug_flag; request->log.func = vradlog_request; request->username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY); request->password = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY); return request; }
static void peerip_clients_config(void) { struct client_t *c; struct peerip_config_t *pe; struct client_udp_t *udpclient; char *s; union sockaddr_u sa; /* large enough for also IPv6 address */ socklen_t addr_len = sizeof(sa); for (pe = peerip_config; (pe); pe = pe->next) { hlog(LOG_DEBUG, "Setting up UDP peer %s (%s)", pe->name, pe->host); udpclient = client_udp_find(udppeers, pe->af, pe->local_port); if (!udpclient) { hlog(LOG_ERR, "Failed to find UDP socket on port %d for peer %s (%s)", pe->local_port, pe->name, pe->host); continue; } c = client_alloc(); if (!c) { hlog(LOG_ERR, "peerip_clients_config: client_alloc returned NULL"); abort(); } c->fd = -1; // Right, this client will never have a socket of it's own. c->ai_protocol = IPPROTO_UDP; c->portnum = pe->local_port; // local port c->state = CSTATE_COREPEER; c->validated = VALIDATED_WEAK; c->flags = CLFLAGS_UPLINKPORT; c->handler_line_in = &incoming_handler; memcpy((void *)&c->udpaddr.sa, (void *)pe->ai->ai_addr, pe->ai->ai_addrlen); c->udpaddrlen = pe->ai->ai_addrlen; c->udp_port = pe->remote_port; // remote port c->addr = c->udpaddr; c->udpclient = udpclient; //c->portaccount = l->portaccount; c->keepalive = tick + keepalive_interval; c->last_read = tick; /* not simulated time */ inbound_connects_account(3, c->udpclient->portaccount); /* "3" = udp, not listening.. */ /* set up peer serverid to username */ strncpy(c->username, pe->serverid, sizeof(c->username)); c->username[sizeof(c->username)-1] = 0; c->username_len = strlen(c->username); /* convert client address to string */ s = strsockaddr( &c->udpaddr.sa, c->udpaddrlen ); /* text format of client's IP address + port */ strncpy(c->addr_rem, s, sizeof(c->addr_rem)); c->addr_rem[sizeof(c->addr_rem)-1] = 0; hfree(s); /* hex format of client's IP address + port */ s = hexsockaddr( &c->udpaddr.sa, c->udpaddrlen ); strncpy(c->addr_hex, s, sizeof(c->addr_hex)); c->addr_hex[sizeof(c->addr_hex)-1] = 0; hfree(s); /* text format of servers' connected IP address + port */ addr_len = sizeof(sa); if (getsockname(c->udpclient->fd, &sa.sa, &addr_len) == 0) { /* Fails very rarely.. */ /* present my socket end address as a malloced string... */ s = strsockaddr( &sa.sa, addr_len ); } else { hlog(LOG_ERR, "Peer config: getsockname on udpclient->fd failed: %s", strerror(errno)); s = hstrdup( "um" ); /* Server's bound IP address.. TODO: what? */ } strncpy(c->addr_loc, s, sizeof(c->addr_loc)); c->addr_loc[sizeof(c->addr_loc)-1] = 0; hfree(s); /* pass the client to the first worker thread */ if (pass_client_to_worker(worker_threads, c)) { hlog(LOG_ERR, "Failed to pass UDP peer %s (%s) to worker", pe->name, pe->host); client_free(c); } } }