4697-1 (Реализация сети в операционной системе Linux), страница 2

2016-07-30СтудИзба

Описание файла

Документ из архива "Реализация сети в операционной системе Linux", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "4697-1"

Текст 2 страницы из документа "4697-1"

#endif

#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)

struct ipx_opt af_ipx;

#endif

#if defined (CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE)

struct dn_scp dn;

#endif

#if defined (CONFIG_PACKET) || defined(CONFIG_PACKET_MODULE)

struct packet_opt *af_packet;

#endif

#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)

x25_cb *x25;

#endif

#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)

ax25_cb *ax25;

#endif

#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)

nr_cb *nr;

#endif

#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE)

rose_cb *rose;

#endif

#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE)

struct pppox_opt *pppox;

#endif

#ifdef CONFIG_NETLINK

struct netlink_opt *af_netlink;

#endif

#if defined(CONFIG_ECONET) || defined(CONFIG_ECONET_MODULE)

struct econet_opt *af_econet;

#endif

#if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE)

struct atm_vcc *af_atm;

#endif

#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)

struct irda_sock *irda;

#endif

#if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE)

struct wanpipe_opt *af_wanpipe;

#endif

} protinfo;

/* This part is used for the timeout functions. */

struct timer_list timer; /* This is the sock cleanup timer. */

struct timeval stamp;

/* Identd and reporting IO signals */

struct socket *socket;

/* RPC and TUX layer private data */

void *user_data;

/* Callbacks */

void (*state_change)(struct sock *sk);

void (*data_ready)(struct sock *sk,int bytes);

void (*write_space)(struct sock *sk);

void (*error_report)(struct sock *sk);

int (*backlog_rcv) (struct sock *sk,

struct sk_buff *skb);

void (*destruct)(struct sock *sk);

};

Эта структура очень широко используется и имеет много hacks зависящих от конфигурации как видим для каждого протокола здесь найдется местечко

Сокеты проходят через процесс маршрутизации только один раз для каждого маршрута. Они содержат указатель на маршрут struct sock- >dst_cache* и вызывают ip_route_connect (net/route.h) для нахождения маршрута информация записывается в dst_cache и сокет дальше использует её не повторяя операции поиска маршрута пока не случится что-то необычное в этом и есть смысл connect

Установление соединения

Рассмотрим стандартный пример

/* look up host */

server = gethostbyname(SERVER_NAME);

/* get socket */

sockfd = socket(AF_INET, SOCK_STREAM, 0);

/* set up address */

address.sin_family = AF_INET;

address.sin_port = htons(PORT_NUM);

memcpy(&address.sin_addr,server->h_addr,server->h_length);

/* connect to server */

connect(sockfd, &address, sizeof(address));

socket создаёт обект сокета определенного типа и инициализирует его также делает дефолтовские очереди (incoming,outgoing,error,backlog) и заголовок TCP

connect определяет маршруты вызывая протокольно зависимые функции (tcp_v4_connect(),udp_connect()) net/socket.c

asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr, int addrlen)

{

................................

err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,

sock->file->f_flags);

..........................

}

int sock_create(int family, int type, int protocol, struct socket **res)

{

.....................................

//cоздаем протокольно зависимый сокет!

//--------------------------------------

if ((i = net_families[family]->create(sock, protocol)) < 0)

{

sock_release(sock);

goto out;

}

.................

}

Функции

Socket

Проверяем ошибки

Выделяем память

Ложим сокет в список inode

Устанавливаем указатели на протокольно зависимые части

Сохраняем данные про тип и параметры сокета

Устанавливаем сокет в положение закрыт

Инициализируем очереди пакетов

Connect

Проверяем ошибки

Определяем Маршрут

Проверяем кэш

Смотрим в FIB

Создаем новую запись в таблице маршрутизации

Заполняем её и возвращаем

Сохраняем указатель на запись маршрутизации в сокете

Вызываем протокольно зависимую функцию connect

Устанавливаем сокет в соединенный

Также надо не забыть закрыть сокет

Close вызывает sock_close in socket.c

void sock_release(struct socket *sock)

{

if (sock->ops)

sock->ops->release(sock);

...........................

}

а та через цепочку вызовов протокольнозависимую функцию

Дополнительные функции

void inet_sock_release(struct sock *sk) -net/ipv4/af_inet.c

назвние говорит за себя + хороший комментарий Алана Коха

fib_lookup() - include/net/ip_fib.h

возвращает маршрут .Написана русским -Кузнецов!

fn_hach_lookup net/fib_hash.c

возвращает маршрут по адресу

inet_create net/ipv4/af_inet.c

создает сокет

inet_release

ip_route_connect

вызывает ip_route_output для определении адреса назначения

ip_route_output

ip_route_output_slow

rt_intern_hash полезные для маршрутизации функции

sock_close()

sock_create()

sock_init_data net/core/sock.c инициализирует основные поля сокета

sock_release net/socket.c

sys_socket

tcp_close net/ipv4/tcp.c

устанавливает флаг FYN

tpc_connect net/ipv4/tpc_output.c

сохдает пакеты для соединения с установленным размером окна

и соответствующими битами, ложит пакет в очередь и выpывает

tcp_transmit_skb чтоб послать пакет

tcp_transmit_skb -заполняет заголовок пакета и передает его

на уроветь IP

tcp_v4_connect()

вызывает ip_route_connect

создает соединительный пакет и вызывает tcp_connect

udp_close

udp_connect

Обмен данными

Эта часть описывает процесс обмена данными между различными уровнями ядра и сети Когда приложение отправляет данные то оно пишет в сокет тот в своб очередь определяет свой тип и вызывает соответствующую функцию,та передает данные протоколу транспортного уровня(tcp,udp) функции етого уровня создают структуру sk_buff,копируют в неё данные заполняют заголовок своего уровня,считают контрольную сумму и шлют на уровень IP.Там дописывается заголовок ip,checksum,возможно пакет фраг менторуется и шлётся на xmit очередь сетевого девайса ,тот посылает пакет в сеть.

dev_queue_xmit() - net/core/dev.c

spin_lock_bh() -блокируем девайс

если у него есть очередь

calls enqueue() добавляем пакет

calls qdis() пробуждаем девайс

else calls dev->hard_start_xmit()

calls spin_unlock_bh() освобождаем девайс

DEVICE->hard_start_xmit() - зависит от девайса, drivers/net/DEVICE.c

в общем проверяет открыто ли устройство

посылает заголовок

говорит системной шине послать пакет

обновляет статус

inet_sendmsg() - net/ipv4/af_inet.c

int inet_sendmsg(struct socket *sock, struct msghdr *msg, int size,

struct scm_cookie *scm)

{

struct sock *sk = sock->sk;

/*биндим сокет. */

if (sk->num==0 && inet_autobind(sk) != 0)

return -EAGAIN;

вызываем функцию протокола чтоб послать данные

return sk->prot->sendmsg(sk, msg, size);

}

ip_build_xmit - net/ipv4/ip_output.c (604)

calls sock_alloc_send_skb() выделяем память

=заголовочек=

if(!sk->protinfo.af_inet.hdrincl) {

iph->version=4;

iph->ihl=5;

iph->tos=sk->protinfo.af_inet.tos;

iph->tot_len = htons(length);

iph->frag_off = df;

iph->ttl=sk->protinfo.af_inet.mc_ttl;

ip_select_ident(iph, &rt->u.dst, sk);

if (rt->rt_type != RTN_MULTICAST)

iph->ttl=sk->protinfo.af_inet.ttl;

iph->protocol=sk->protocol;

iph->saddr=rt->rt_src;

iph->daddr=rt->rt_dst;

iph->check=0;

iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

err = getfrag(frag, ((char *)iph)+iph->ihl*4,0, length-iph->ihl*4);

}

calls getfrag() копируем данные у юзера

returns rt->u.dst.output() [= dev_queue_xmit()]

ip_queue_xmit() - net/ipv4/ip_output.c (234)

cмотри маршрут

достраиваем ip заголовок

фрагментирум если надо

adds IP checksum

calls skb->dst->output() [= dev_queue_xmit()]

qdisc_restart() - net/sched/sch_generic.c (50)

вырываем пакет из очереди

calls dev->hard_start_xmit()

обновляем статистику

if если ошибка опять стввим пакет в очередь

sock_sendmsg() - net/socket.c (325)

проверяем права и всё такое

calls scm_sendmsg() [socket control message]

шлёмс данные

calls sock->ops[inet]->sendmsg() and destroys scm

>>> sock_write() - net/socket.c (399)

calls socki_lookup() accоциируем сокет с inode

заполняем заголовок сообщения

returns sock_sendmsg()

tcp_sendmsg() - net/ipv4/tcp.c (755)

ждемс соединения

skb = tcp_alloc_pskb память

calls csum_and_copy_from_user() делаем checksum & копируем

calls tcp_send_skb()

tcp_send_skb() - net/ipv4/tcp_output.c (160)

это главная routine посылки буфера

мы ставим буфер в очередь и решаем оставить его там или послать

calls __skb_queue_tail() добавляем в очередь

calls tcp_transmit_skb() если может

tcp_transmit_skb() - net/ipv4/tcp_output.c (77)

строим заголовок tcp и чексумму

calls tcp_build_and_update_options()

проверяем ACKs,SYN

calls tp->af_specific[ip]->queue_xmit()

udp_getfrag() - net/ipv4/udp.c

копируем из адресного пространства пользователя и добавляем checksum

udp_sendmsg() - net/ipv4/udp.c

проверяем флаги и тд

заполняем заголовок

проверяем мультикаст

заполняем маршутную информацию

calls ip_build_xmit()

обновляем статистику udp

returns err

Получение данных

Получение данных начинается с прерывания от сетевой карты. Драйвер девайса выделяет память и пересылает данные в то пространство. Потом передает пакет в связующий уровень который вызывает bottom-halv,которое обрабатывает событие вне прерывания пересылая данные на уровень выше -ip.Тот проверяет ошибки фрагменты, маршрутизирует пакет или отсылает на уровень выше(tcp || udp) Этот уровень снова проверяет ошибки определяет сокет которому предназначен пакет и ложит его в очередь сокета. Тот в свою очередь будит пользовательский процесс и копирует данные в его буфер.

Чтение из сокета(1)

Пытаемся что-то прочитать(и засыпаем)

Заполняем заголовок сообщения указателем на буфер(сокет)

проверяем простые ошибки

передаем сообщение inet сокету

Получение пакета

Пробуждение устройства(прерывание)

проверка девайса

Получение заголовка

выделение памяти

ложим пакет в то место судя по всему используя DMA

ставим пакет в очередь

выставляем флаг запуска bottom-halv

BottomHalv

Запуск сетевого ботом-халва

Пересылка пакетов из девайса чтоб не было прерываний

пересылка пакетов на уровень ip

очистка очереди отсылки

возврат

Уровень IP

Проверка ошибок

Дефрагментация если необходимо

Определение маршрута(форвардить или нет)

Отсылка пакета по назначению(TCP||UDP||forwarding)

Получение пакета в UDP

Проверка ошибок

проверка сокета назначения

пересылка пакета в очередь сокета

пробуждения ждущего процесса

Получение TCP

Проверка флагов и ошибок а также не был ли получен пакет ранее

Определение сокета

пересылка пакета в очередь сокета

пробуждения ждущего процесса

Чтение из сокета(2)

Пробуждение процесса

Вызов соответствуюшей функции доставки(udp ||tcp) в буфер пользователя

Возврат

IP forwarding

Рассмотрим подробнее процесс форвардинга пакетов

Сначала идет проверка TTL и уменьшение его на 1 Проверка пакета на наличие действительного маршрута если такого нет то отсылается соответствующее icmp сообщение копирование пакета в новый буфер и освобождение старого Установка нужных ip опций фрагменторование если необходимо отправка пакета на нужный девайс

DEVICE_rx() девайсно зависимая функция,

пример drivers/net/de600.c

здесь я попытаюсь перевести замечательные комментарии автора

Linux driver for the D-Link DE-600 Ethernet pocket adapter.

Свежие статьи
Популярно сейчас
Зачем заказывать выполнение своего задания, если оно уже было выполнено много много раз? Его можно просто купить или даже скачать бесплатно на СтудИзбе. Найдите нужный учебный материал у нас!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5184
Авторов
на СтудИзбе
435
Средний доход
с одного платного файла
Обучение Подробнее