Atividade 5 (obrigatória): emulador de um servidor inetd
Atualizado em 13 Out 2008
O objetivo desta atividade é escrever um emulador da funcionalidade provida pelo
superservidor internet inetd, do Unix (*).
Vamos chamá-lo de user_inetd,
pois o mesmo vai executar como processo de usuário. Todos os requisitos básicos
detalhados nas notas de aula deverão
ser suportados, com algumas modificações simples a serem descritas:
- o arquivo de registro de serviços a serem disparados pelo user_inetd deve ter
o mesmo formato do arquivo textual inetd.conf
(veja as notas de aula ),
acrescentando um campo adicional que
conterá a porta do serviço (coloque como número da porta 1000 +
(número do seu grupo*10 se turma A + n ou número do seu grupo*11 se tirma B + n),
onde n vale 1, 2, etc, para distinguir os serviços a serem suportados(**)).
Para obter os campos (que estão num formato livre) de cada linha do arquivo você pode usar
as funções da biblioteca de tratmento de cadeias ("strings") da linguagem C. Veja
aqui
um resumo das mesmas.
- os serviços udp terão a categoria wait e os serviços TCP terão a categoria
nowait, com o significado usual;
- user_inetd deverá registrar num arquivo de log a data/hora em que o serviço
foi solicitado, o IP e a porta do cliente, assim como a data/hora em que o serviço
foi concluído (encontre uma maneira de associar o registro de conclusão
com o registro de início do serviço);
- user_inetd deverá ser testado com pelo menos 3 "serviços" simples:
- um servidor de eco iterativo como o das atividades 1 ou 2.1, com a diferença de que
o mesmo deverá terminar após cada conexão fechada pelo cliente.
- um servidor TCP que guarda no arquivo de log a data e hora corrente
, o IP, a porta do cliente,
e devolve ao cliente a data e hora (de forma semelhante ao serviço daytime na porta 13).
- um servidor UDP que guarda no arquivo e log a data e hora corrente, o IP, a porta do cliente,
e devolve ao cliente a data e hora. Existe uma dificuldade aqui que é o fato de
o cliente só enviar um datagrama que é recebido por user_inetd; desta forma
o servidor UDP por ele disparado não tem condições de saber o IP e a porta do cliente.
Por isto é preciso que user_inetd não retire do kernel UDP o datagrama recebido,
porém possa analisar o seu conteúdo. Isto é possível
se user_inetd ao invocar recvfrom colocar no campo de flags (normalmente 0) a constante
MSG_PEEK, permitindo assim ao servidor UDP receber o datagrama invocando recvfrom()
da forma usual.
Você deverá escrever clientes para estes dois servidores.
- (opcional) um servidor simples qualquer da sua escolha.
- user_inetd deverá ser instalado como um daemon (tomando os cuidados
detalhados na atividade 4 e abaixo (***)) ; faça isto apenas após depurar as outras funções acima descritas.
Junto com a demonstração no laboratório Você deverá prover impressão dos fontes
de todos os servidores desenvolvidos e uma impressão de parte do arquivo de log.
Não é necessário submeter o código dos clientes.
(*) Linux utiliza um utilitário similar ao inetd, xinetd, cujo arquivo de configuração,
xinetd.conf, é semelhante, mas diferente do inetd.conf.
(**) A finalidade dessa fórmula complicada é evitar conflitos de portas entre os diversos grupos.
(***) o seu daemon permanecerá executando na máquina mesmo após você dar "logout".
Por isso, descubra o seu pid usando o comando: ps -A e mate-o
via comando kill -9 pid_daemon.
Além disso, após os testes, remova o seu arquivo de log do diretório /tmp.