Нужна помощь в понимании сопоставления отправления, sendto, sendmsg в пространстве пользователя с sendmsg в пространстве ядра - PullRequest
1 голос
/ 15 июня 2010

Я пытаюсь реализовать свой собственный протокол транспортного уровня в Linux для эксперимента. Я собираюсь использовать интерфейс сокетов и добавить свой протокол, используя sock_register. Для proto_ops я вижу, что параметры для sendmsg и recvmsg следующие (struct kiocb * iocb, struct socket * sock, struct msghdr * msg, size_t len, int flags). Но есть три типа пользовательских api send, sendto, sendmsg. Из этих трех только sendmsg содержит параметр для msghdr. Я обнаружил, что два других API несовместимы с параметрами, предоставленными ядром для моей функции sendmsg пространства ядра. Так что же происходит, когда мы используем API-интерфейсы send и sendto в пространстве пользователя? Надеюсь, мне ясно ..

Спасибо, Bala

Ответы [ 2 ]

1 голос
/ 16 июня 2010

send() реализовано в терминах sendto(): send(s, buf, len, flags); эквивалентно sendto(s, buf, len, flags, NULL, 0);

sendto() в свою очередь реализуется в терминах sendmsg(). send(s, buf, len, flags, addr, addr_len); реализуется с помощью (с точки зрения интерфейса пользовательского пространства):

struct iovec iov =  { 
    .iov_base = buf, 
    .iov_len = len
};
struct msghdr msg = { 
    .msg_name = addr, 
    .msg_namelen = addr_len, 
    .msg_iov = &iov, 
    .msg_iovlen = 1,
    .msg_control = NULL,
    .msg_controllen = 0
};

return sendmsg(s, &msg, flags);

Интерфейс пространства ядра немного отличается - например, вы получаете параметр kiocb - но основная идея та же. send() или sendto() преобразуется в sendmsg() с msghdr, который указывает на один iovec, который ссылается на буфер.

0 голосов
/ 15 июня 2010

Если вы знакомы с механизмом системных вызовов - начните с net/socket.c и следуйте цепочке вызовов - это более или менее понятно.

...