int
thr_demarshal_set_buffer(cf_socket *sock, buffer_type type, int size)
{
	static int rcv_max = -1;
	static int snd_max = -1;

	const char *proc;
	int *max;

	switch (type) {
	case BUFFER_TYPE_RECEIVE:
		proc = "/proc/sys/net/core/rmem_max";
		max = &rcv_max;
		break;

	case BUFFER_TYPE_SEND:
		proc = "/proc/sys/net/core/wmem_max";
		max = &snd_max;
		break;

	default:
		cf_crash(AS_DEMARSHAL, "Invalid buffer type: %d", (int32_t)type);
		return -1; // cf_crash() should have a "noreturn" attribute, but is a macro
	}

	int tmp = ck_pr_load_int(max);

	if (tmp < 0) {
		if (thr_demarshal_read_integer(proc, &tmp) < 0) {
			cf_warning(AS_DEMARSHAL, "Failed to read %s; should be at least %d. Please verify.", proc, size);
			tmp = size;
		}
	}

	if (tmp < size) {
		cf_warning(AS_DEMARSHAL, "Buffer limit is %d, should be at least %d. Please set %s accordingly.",
				tmp, size, proc);
		return -1;
	}

	ck_pr_cas_int(max, -1, tmp);

	switch (type) {
	case BUFFER_TYPE_RECEIVE:
		cf_socket_set_receive_buffer(sock, size);
		break;

	case BUFFER_TYPE_SEND:
		cf_socket_set_send_buffer(sock, size);
		break;
	}

	return 0;
}
int
thr_demarshal_set_buffer(int fd, int option, int size)
{
	static int rcv_max = -1;
	static int snd_max = -1;

	const char *proc;
	int *max;

	switch (option) {
	case SO_RCVBUF:
		proc = "/proc/sys/net/core/rmem_max";
		max = &rcv_max;
		break;

	case SO_SNDBUF:
		proc = "/proc/sys/net/core/wmem_max";
		max = &snd_max;
		break;

	default:
		cf_crash(AS_DEMARSHAL, "Invalid option: %d", option);
		return -1; // cf_crash() should have a "noreturn" attribute, but is a macro
	}

	int tmp = ck_pr_load_int(max);

	if (tmp < 0) {
		if (thr_demarshal_read_integer(proc, &tmp) < 0) {
			cf_warning(AS_DEMARSHAL, "Failed to read %s; should be at least %d. Please verify.", proc, size);
			tmp = size;
		}
	}

	if (tmp < size) {
		cf_warning(AS_DEMARSHAL, "Buffer limit is %d, should be at least %d. Please set %s accordingly.",
				tmp, size, proc);
		return -1;
	}

	ck_pr_cas_int(max, -1, tmp);

	if (setsockopt(fd, SOL_SOCKET, option, &size, sizeof size) < 0) {
		cf_crash(AS_DEMARSHAL, "Failed to set socket buffer for FD %d, size %d, error %d (%s)",
				fd, size, errno, strerror(errno));
	}

	return 0;
}