static int on_request_recv_callback(nghttp2_session *session, int32_t stream_id, void *user_data) { int fd; http2_session_data *session_data = (http2_session_data*)user_data; http2_stream_data *stream_data; nghttp2_nv hdrs[] = { MAKE_NV(":status", "200") }; char *rel_path; stream_data = (http2_stream_data*)nghttp2_session_get_stream_user_data (session, stream_id); if(!stream_data->request_path) { if(error_reply(session, stream_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } return 0; } fprintf(stderr, "%s GET %s\n", session_data->client_addr, stream_data->request_path); if(!check_path(stream_data->request_path)) { if(error_reply(session, stream_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } return 0; } for(rel_path = stream_data->request_path; *rel_path == '/'; ++rel_path); fd = open(rel_path, O_RDONLY); if(fd == -1) { if(error_reply(session, stream_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } return 0; } stream_data->fd = fd; if(send_response(session, stream_id, hdrs, ARRLEN(hdrs), fd) != 0) { close(fd); return NGHTTP2_ERR_CALLBACK_FAILURE; } return 0; }
void error_quit(char *msg) { char buf[BUFSIZE]; if (errno == 0) snprintf(buf, BUFSIZE, "%s", msg); else snprintf(buf, BUFSIZE, "%s: %s", msg, strerror(errno)); error_reply(buf); exit(1); }
static void query_zones(wrt_client_t *c, mrp_json_t *req) { const char *type = RESWRT_QUERY_ZONES; mrp_json_t *reply; const char **zones; size_t nzone; int seq; if (!mrp_json_get_integer(req, "seq", &seq)) { ignore_invalid_request(c, req, "missing 'seq' field"); return; } zones = mrp_zone_get_all_names(0, NULL); if (zones == NULL) { error_reply(c, type, seq, ENOMEM, "failed to query zone names"); return; } reply = alloc_reply(type, seq); if (reply == NULL) mrp_log_error("Failed to allocate WRT resource reply."); nzone = 0; for (nzone = 0; zones[nzone] != NULL; nzone++) ; if (mrp_json_add_integer (reply, "status", 0) && mrp_json_add_string_array(reply, "zones" , zones, nzone)) send_message(c, reply); mrp_json_unref(reply); mrp_free(zones); }
static void query_classes(wrt_client_t *c, mrp_json_t *req) { const char *type = RESWRT_QUERY_CLASSES; mrp_json_t *reply; const char **classes; size_t nclass; int seq; if (!mrp_json_get_integer(req, "seq", &seq)) { ignore_invalid_request(c, req, "missing 'seq' field"); return; } classes = mrp_application_class_get_all_names(0, NULL); if (classes == NULL) { error_reply(c, type, seq, ENOMEM, "failed to query class names"); return; } reply = alloc_reply(type, seq); if (reply == NULL) return; nclass = 0; for (nclass = 0; classes[nclass] != NULL; nclass++) ; if (mrp_json_add_integer (reply, "status" , 0) && mrp_json_add_string_array(reply, "classes", classes, nclass)) send_message(c, reply); mrp_json_unref(reply); mrp_free(classes); }
static void client_input(struct socket_info *si) { struct client_connection *c = si->udata; char buf[1500]; int n; int got = 0; int ok; if (!c) croak(1, "client_input: no client_connection information"); if ( (n = read(si->fd, buf, 1500)) == -1) { switch (errno) { case EPIPE: client_gone(si); return; case ECONNRESET: client_gone(si); return; } croak(1, "client_input: read error"); } if (n == 0) { client_gone(si); return; } msgpack_unpacker_reserve_buffer(&c->unpacker, n); memcpy(msgpack_unpacker_buffer(&c->unpacker), buf, n); msgpack_unpacker_buffer_consumed(&c->unpacker, n); while (msgpack_unpacker_next(&c->unpacker, &c->input)) { msgpack_object *o; uint32_t cid; uint32_t type; got = 1; ok = -1; PS.client_requests++; si->PS.client_requests++; //if (!opt_quiet) { // printf("got client input: "); // msgpack_object_print(stdout, c->input.data); // printf("\n"); //} o = &c->input.data; if (o->type != MSGPACK_OBJECT_ARRAY) { error_reply(si, RT_ERROR, 0, "Request is not an array"); goto end; } if (o->via.array.size < 1) { error_reply(si, RT_ERROR, 0, "Request is an empty array"); goto end; } if (o->via.array.size < 2) { error_reply(si, RT_ERROR, 0, "Request without an id"); goto end; } if (o->via.array.ptr[RI_CID].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { error_reply(si, RT_ERROR, 0, "Request id is not a positive integer"); goto end; } cid = o->via.array.ptr[RI_CID].via.u64; if (o->via.array.ptr[RI_TYPE].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { error_reply(si, RT_ERROR, cid, "Request type is not a positive integer"); goto end; } type = o->via.array.ptr[RI_TYPE].via.u64; switch (type) { case RT_SETOPT: ok = handle_setopt_request(si, cid, o); break; case RT_GETOPT: ok = handle_getopt_request(si, cid, o); break; case RT_INFO: ok = handle_info_request(si, cid, o); break; case RT_DEST_INFO: ok = handle_dest_info_request(si, cid, o); break; case RT_GET: ok = handle_get_request(si, cid, o); break; case RT_GETTABLE: ok = handle_gettable_request(si, cid, o); break; default: error_reply(si, type|RT_ERROR, cid, "Unknown request type"); } end: if (ok < 0) { PS.invalid_requests++; si->PS.invalid_requests++; } } if (got) { msgpack_unpacker_expand_buffer(&c->unpacker, 0); } }
void notify(const struct sockaddr_nl *nlp, struct nlmsghdr *nlmsgp) { int len; int host_len; unsigned char cmd; struct in_addr any; struct iovec iov[NUM_RESP]; struct rtmsg *rtmp; struct rtattr *attrs[RTA_MAX + 1]; switch (nlmsgp->nlmsg_type) { case RTM_NEWROUTE: cmd = RTM_CMD_ROUTE_ADD; break; case RTM_DELROUTE: cmd = RTM_CMD_ROUTE_DEL; break; default: error_reply("not a route"); return; } len = nlmsgp->nlmsg_len - NLMSG_LENGTH(sizeof(*nlmsgp)); if (len < 0) { error_reply("wrong message length"); return; } rtmp = NLMSG_DATA(nlmsgp); /* Don't notify routes added by ourselves. */ if (rtmp->rtm_protocol == RTPROT_ROUTEMACHINE) return; if (rtmp->rtm_table != RT_TABLE_MAIN) return; switch (rtmp->rtm_family) { case AF_INET: host_len = 4; break; case AF_INET6: host_len = 16; break; default: error_reply("bad message family"); return; } parse_attrs(attrs, RTM_RTA(rtmp), len); iov[CMD].iov_base = &cmd; iov[CMD].iov_len = 1; iov[MASK].iov_base = &rtmp->rtm_dst_len; iov[MASK].iov_len = 1; any.s_addr = INADDR_ANY; if (attrs[RTA_DST] != NULL) { iov[DST].iov_base = RTA_DATA(attrs[RTA_DST]); iov[DST].iov_len = (rtmp->rtm_dst_len + 7)/8; } else { iov[DST].iov_base = &any; iov[DST].iov_len = sizeof(any); } if (attrs[RTA_GATEWAY] != NULL) { iov[GW].iov_base = RTA_DATA(attrs[RTA_GATEWAY]); iov[GW].iov_len = host_len; } else { iov[GW].iov_base = &any; iov[GW].iov_len = sizeof(any); } if (attrs[RTA_PRIORITY] != NULL) { uint32_t prio = htonl(*(uint32_t *)RTA_DATA(attrs[RTA_PRIORITY])); iov[PRIO].iov_base = &prio; iov[PRIO].iov_len = 4; } else { uint32_t prio = htonl(0); iov[PRIO].iov_base = &prio; iov[PRIO].iov_len = 4; } writev(STDOUT_FILENO, iov, NUM_RESP); }
static void query_resources(wrt_client_t *c, mrp_json_t *req) { const char *type = RESWRT_QUERY_RESOURCES; mrp_json_t *reply, *rarr, *r, *ao; const char **resources; int seq, cnt; mrp_attr_t *attrs, *a; mrp_attr_t buf[ATTRIBUTE_MAX]; uint32_t id; if (!mrp_json_get_integer(req, "seq", &seq)) { ignore_invalid_request(c, req, "missing 'seq' field"); return; } rarr = r = ao = NULL; resources = mrp_resource_definition_get_all_names(0, NULL); if (resources == NULL) { error_reply(c, type, seq, ENOMEM, "failed to query class names"); return; } reply = alloc_reply(type, seq); if (reply == NULL) return; rarr = mrp_json_create(MRP_JSON_ARRAY); if (rarr == NULL) goto fail; for (id = 0; resources[id]; id++) { r = mrp_json_create(MRP_JSON_OBJECT); if (r == NULL) goto fail; if (!mrp_json_add_string (r, "name", resources[id])) goto fail; attrs = mrp_resource_definition_read_all_attributes(id, ATTRIBUTE_MAX, buf); ao = mrp_json_create(MRP_JSON_OBJECT); if (ao == NULL) goto fail; for (a = attrs, cnt = 0; a->name; a++, cnt++) { switch (a->type) { case mqi_string: if (!mrp_json_add_string(ao, a->name, a->value.string)) goto fail; break; case mqi_integer: case mqi_unsignd: if (!mrp_json_add_integer(ao, a->name, a->value.integer)) goto fail; break; case mqi_floating: if (!mrp_json_add_double(ao, a->name, a->value.floating)) goto fail; break; default: mrp_log_error("attribute '%s' of resource '%s' " "has unknown type %d", a->name, resources[id], a->type); break; } } if (cnt > 0) mrp_json_add(r, "attributes", ao); else mrp_json_unref(ao); ao = NULL; if (!mrp_json_array_append(rarr, r)) goto fail; else r = NULL; } if (mrp_json_add_integer(reply, "status" , 0)) { mrp_json_add (reply, "resources", rarr); send_message(c, reply); } mrp_json_unref(reply); mrp_free(resources); return; fail: mrp_json_unref(reply); mrp_json_unref(rarr); mrp_json_unref(r); mrp_json_unref(ao); mrp_free(resources); }