paulo1205
(usa Ubuntu)
Enviado em 07/03/2019 - 01:53h
Pensando devagar, à medida em que entendo seu código.
Em
main(), como você já tem o valor de
addrlen após a chamada a
accept(), você poderia simplificar tanto
realloc_table() quanto a atribuição de endereço usando
memset(), as quais, em vez de usar
ifs para decidir o tamanho com base no tipo do
socket, poderiam se beneficiar do valor já entregue à variável
addrlen. Isso ajudaria a facilitar a leitura do código.
Fazendo isso, a preocupação com o tipo do
socket ficaria apenas nas funções em que isso é relevante, que são
check_addr() e
show_addr(). Eu acho realmente que se você diminuir o número de conversões entre tipos de ponteiros diferentes, o programa vai ficar mais fácil de ser entendido e mantido.
Compilando e rodando o seu programa e testando-o a partir de três endereços diferentes (meu IP de LAN,
127.0.0.1 e
::1), o primeiro endereço funciona, e os seguintes, não (mesmo trocando a ordem entre eles). Mais do que isso, rodando o servidor sob o
valgrind, ele indica tentativa de ler fora da região de memória alocada em uma chamada a
check_addr(). Há portanto, um erro ou na alocação ou no laço de verificação de endereços.
Recompilando o programa com a opção
-g, reexecutei-o com o valgrind e vi que ele mostrou que há uma tentativa em
check_addr() de acesso a 36 bytes em um objeto que foi alocado com apenas 28 bytes em
realloc_table(). 28 bytes é o tamanho de uma
struct sockaddr_in6, logo o erro está com certeza em
check_addr().
Achei o problema! (E não sei como não o vi antes, sem o valgrind!)
Em
check_addr(), você diz primeiro que “
addrs6=(struct sockaddr_in6*)buff_addr_table[i];”, logo pega apenas um endereço da tabela. Não obstante, ao chamar
memcmp(), você aplica novamente o índice
i ao ponteiro
addrs6, que se refere a um endereço só. Ali há de se tirar o índice, e dizer apenas “
addrs6->sin6_addr.s6_addr”. Problema semelhante ocorre com o teste de IPv4, e tem de ser corrigido também ali.
Aliás, esse é um caso em que o nome da variável atrapalha o diagnóstico. Ao chamá-la de
addrs6 (e
addrs4), esse “s” dá uma ideia de plural, como se você ainda tivesse um
array, quando na verdade já isolou um único endereço. Seria bom, portanto, alterar também o nome da variável.
... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)