LINUX.ORG.RU

И еще немножечко sctp

 


0

1

sctp-шный сервер при переключении на вторичный адрес не принимает новых соединений. Старые продолжают работать, а вот новые не принимает. Вот что пишет wireshark: ICMP 126 Destination unreachable (Host unreachable) Внимание вопрос, в чем баг?



Последнее исправление: ReinBegriff (всего исправлений: 1)

Внимание. Где код? Или дамп tcpdump? Из libastral доносятся сообщения, что клиент не правильно работает с SCTP_INIT пакетами.

greek_31 ★★
()
Ответ на: комментарий от greek_31
//server
#include "ace/SOCK_SEQPACK_Acceptor.h"
#include "ace/IPC_SAP.h"
#include "ace/SOCK.h"
#include <netinet/sctp.h>
#include <string.h>

#define PORT_NUM 5002

int main (int argc, char **argv)
{
  ACE_SOCK_SEQPACK_Acceptor AcceptorSocket;
  ACE_SOCK_SEQPACK_Association Stream;
  
  pid_t childpid;
  
  int count = 0;
  int len = 0;
  char buf[BUFSIZ];
  
  const char *primary_addr = "192.168.1.2";
  const char *secondary_host_names[] = {"192.168.1.3"};
//задаем адреса сервера   
  ACE_Multihomed_INET_Addr ServerAddr (PORT_NUM, 
				       primary_addr, 
				       1, 
				       AF_INET,
				       secondary_host_names,
				       1
				      );
//открытие сокета
  if (-1 == AcceptorSocket.open (ServerAddr, 1))
    {
      perror("acceptor open ");
      return 1;
    }
//устанавливаем таймеры    
    sctp_paddrparams sctp_parm;

    sctp_parm.spp_pathmaxrxt=3;
    sctp_parm.spp_hbinterval =200;
    len = sizeof(struct sctp_paddrparams);
    AcceptorSocket.set_option(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &sctp_parm,len);

    sctp_rtoinfo rto;
    rto.srto_min=500;
    rto.srto_max=1500;
 
    len = sizeof(struct sctp_rtoinfo);
    AcceptorSocket.set_option(IPPROTO_SCTP, SCTP_RTOINFO, &rto,len);
//цикл приема сообщений
  for(;;)
  { 
    printf("...waiting for client...\n");
    if (-1 == AcceptorSocket.accept(Stream))
    {
      perror("accept error ");
      return 1;
    }
    Stream.enable(ACE_NONBLOCK);
    printf("...client connected...\n");
  
    count=0;    
    for (ssize_t n; (n = Stream.recv_n(buf,sizeof buf)) > 0; )  
    {
      sleep(1);
      printf("client:%d - %s",count++,buf); 
      strcpy(buf,"pong\n");
      Stream.send_n(buf, sizeof(buf));

    }
    Stream.close();
  }
  
  if (-1 == AcceptorSocket.close ()) 
  {
    perror("acceptor close error ");
    return 1;
  }
  return 0;  
}
//client
#include "ace/OS_NS_unistd.h"
#include "ace/SOCK_SEQPACK_Connector.h"
#include <string.h>
#include <netinet/sctp.h>

#define PORT_NUM 5002

int main(int argc, char **argv)
{
  ACE_SOCK_SEQPACK_Connector Connector;
  ACE_SOCK_SEQPACK_Association Stream;
  
  char buf[BUFSIZ];
  int count=0;
  
  const char *primary_addr = "192.168.1.2";
  const char *secondary_host_names[1] = {"192.168.1.3"};
//указываем адрес сервера
  ACE_Multihomed_INET_Addr ServerAddr (
				       PORT_NUM, 
				       primary_addr,
				       1, 
				       AF_INET,
				       secondary_host_names,
				       0
					);
//соединение с сервером
  if (-1 == Connector.connect (Stream,
				ServerAddr,
                               NULL,
                               ACE_Addr::sap_any,
                               1))
  {
    perror("connector.connect error ");
    return 1;
  }
//установка таймеров
  sctp_paddrparams sctp_parm;
  sctp_parm.spp_pathmaxrxt=3;
  sctp_parm.spp_hbinterval =200;
  int len = sizeof(struct sctp_paddrparams);
  Stream.set_option(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &sctp_parm,len);
 
  sctp_rtoinfo rto;
  rto.srto_min=500;
  rto.srto_max=1500;
  len = sizeof(struct sctp_rtoinfo);
  Stream.set_option(IPPROTO_SCTP, SCTP_RTOINFO, &rto,len);
  
  while(1)
  {
//посылаем сообщение
    strcpy(buf,"ping\n");
    Stream.send_n( &buf, sizeof(buf) );
    Stream.recv(&buf,sizeof buf);
    sleep(1);
    printf("%d:%s",count++,buf);
  }
  return Stream.close();
}
ifconfig:
eth0:2    Link encap:Ethernet  HWaddr 00:1d:92:08:bd:0e  
          inet addr:192.168.1.2  Bcast:192.168.1.63  Mask:255.255.255.192
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:3    Link encap:Ethernet  HWaddr 00:1d:92:08:bd:0e  
          inet addr:192.168.1.3  Bcast:192.168.1.3  Mask:255.255.255.252
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

ReinBegriff
() автор топика
Ответ на: комментарий от ReinBegriff

Мда. я работал только с lksctp стэком. Про Ace ничего сказать не могу. К слову, их реализация полностью не соответствует rfc SCTP API(не помню номер). Это печалит.

По-идее, если клиент и сервер работают на одном хосте, клиент не может сделать bind на несуществующий(удаленный alias eth) адрес, но это справедливо только для stream соединений. То есть, до функции .connect() дело не дойдет.

Можно попробывать несколько вариантов диагностики:

  • Использовать, если возможно, 2 интерфейса с проводами. Либо просто 2 хоста с одним интерфейсом. Сейчас похоже всё происходит на одном хосте.
  • В дампе tcpdump просмотреть внимательно пакеты SCTP_INIT и INIT-ACK. Wireshark умеет фильтровать их. Собственно с каких адресов и на какие адреса шлётся INIT и с каких адресов на какие идет INIT-ACK.

И таки да, пришли дамп обмена, с указанием времени отключения интерфейса. Также не плохо было команду, которой отключается alias. И к тому же что такое ACE?

greek_31 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.