Beispiel #1
0
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;
}
Beispiel #2
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);
}
Beispiel #5
0
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);
	}
}
Beispiel #6
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);
}