У меня проблема в MacOS при использовании расширения ядра, которое должно фильтровать сетевой трафик.
Входящие данные прекрасно работают. Однако загрузка данных размером более 500 КБ приводит к внезапно закрытому соединению. Небольшие файлы могут быть загружены без проблем. Это через любой протокол, протестированный на ftp, http, https и т. Д.
Упрощенный код драйвера:
errno_t tl_data_fn(void *cookie, socket_t so, const struct sockaddr *addr, mbuf_t *data, mbuf_t *control, sflt_data_flag_t flags, FilterSocketDataDirection direction) {
if (check_tag(data, gidtag, FILTER_TAG_TYPE, direction == FilterSocketDataDirectionIn ? IN_DONE : OUT_DONE)) {
return 0;
}
if (!cookie) return result;
filter_cookie *f_cookie = get_filter_cookie(cookie);
FilterNotification notification;
if (direction == FilterSocketDataDirectionIn) {
notification.event = FilterEventDataIn;
} else {
notification.event = FilterEventDataOut;
}
notification.socketId = (uint64_t)so;
notification.inputoutput.dataSize = (uint32_t)mbuf_pkthdr_len(*data);
mbuf_copydata(*data, offset, notification.inputoutput.dataSize, notification.inputoutput.data);
ctl_enqueuedata(f_cookie->ctl_ref, f_cookie->ctl_unit, ¬ification, sizeof(FilterNotification), CTL_DATA_EOR);
mbuf_freem(*data);
if (control != NULL && *control != NULL)
mbuf_freem(*control);
return EJUSTRETURN;
}
errno_t tl_data_in_fn(void *cookie, socket_t so, const struct sockaddr *from, mbuf_t *data, mbuf_t *control, sflt_data_flag_t flags) {
return tl_data_fn(cookie, so, from, data, control, flags, FilterSocketDataDirectionIn);
}
errno_t tl_data_out_fn(void *cookie, socket_t so, const struct sockaddr *to, mbuf_t *data, mbuf_t *control, sflt_data_flag_t flags) {
return tl_data_fn(cookie, so, to, data, control, flags, FilterSocketDataDirectionOut);
}errno_t ctl_send(kern_ctl_ref ctl_ref, u_int32_t unit, void *unitinfo, mbuf_t m, int flags) {
FilterClientResponse response;
mbuf_copydata(m, 0, sizeof(response), &response);
mbuf_t data;
mbuf_allocpacket(MBUF_WAITOK, response.dataSize, NULL, &data);
mbuf_copyback(data, 0, response.dataSize, response.data, MBUF_WAITOK);
set_tag(&data, gidtag, FILTER_TAG_TYPE, response.direction == FilterSocketDataDirectionIn ? IN_DONE : OUT_DONE);
if (response.direction == FilterSocketDataDirectionIn) {
sock_inject_data_in((socket_t)response.socketId, NULL, data, NULL, 0);
} else {
sock_inject_data_out((socket_t)response.socketId, NULL, data, NULL, 0);
}
mbuf_freem(m);
return 0;
}
tl_data_in_fn
а также tl_data_out_fn
функции используются в sftl_filter
, ctl_send
используется в kern_ctl_reg
как ctl_send_func
,
Упрощенный код процесса пользовательского пространства:
int s = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
//connect to driver
FilterNotification notification;
while (recv(s, ¬ification, sizeof(FilterNotification), 0) == sizeof(FilterNotification)) {
FilterClientResponse response;
response.socketId = notification.socketId;
response.direction = (notification.event == FilterEventDataIn) ? FilterSocketDataDirectionIn : FilterSocketDataDirectionOut;
response.dataSize = notification.inputoutput.dataSize;
memcpy(response.data, notification.inputoutput.data, notification.inputoutput.dataSize);
send(s, &response, sizeof(response), 0);
}
Любая помощь / совет будет оценен. Kext и репозиторий пользовательских процессов.
Спасибо
Задача ещё не решена.
Других решений пока нет …