Re: Issues with INET sockets through loopback (lo)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tuesday 24 May 2005 14:23, Avi Kivity wrote:
> On Mon, 2005-05-23 at 13:17 +0200, Hans Henrik Happe wrote:
> 
> > I hope that others can comfirm that this is an issue or otherwise explain 
> > why it is supposed behave this way.
> > 
> 
> you might try using udp instead of tcp. this would help determine
> whether the problem is in the tcp stack or the loopback interface.

Now I have tried with SCTP and it works great (no idle CPU time).
So my guess is still that there is a problem in TCP.

I have attached the SCTP program. It's my first attempt at using SCTP, so it's 
not beautiful. The messages get around as expected though.

TripleH ;-)
/* 
 * usage: random-inet <# processes> <# messages>
 */

#include <asm/msr.h>

#include <stdio.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <fcntl.h>
#include <netdb.h>

#include <netinet/sctp.h>

typedef struct {
    struct sockaddr sockadr;
    int len;    
} adr_t;

int get_adr(adr_t *adr, int port) {
   int n;
   struct addrinfo hints, *res;
   char str[6];
    
   memset(&hints, 0, sizeof(struct addrinfo));
    
   hints.ai_flags    = AI_PASSIVE;
   hints.ai_family   = PF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;

   sprintf(str, "%d", port);
   n = getaddrinfo("localhost", str, &hints, &res);

   if (n != 0) {
       fprintf(stderr,
               "getaddrinfo error: [%s]\n",
               gai_strerror(n));
       return -1;    
   }
   
   memcpy(&adr->sockadr, res->ai_addr, sizeof(*res->ai_addr));
   adr->len = sizeof(*res->ai_addr);
      
   freeaddrinfo(res);

   return 0;
}

int init_listen(int port) {
    int n, on=1;
    int sock;    
    struct sockaddr_in name;
   
        
    sock = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
    if (sock == -1) {
        perror("socket");
        return -1;
    }
    
    name.sin_family = PF_INET;
    name.sin_port = htons (port);
    name.sin_addr.s_addr = htonl (INADDR_ANY);
    
    if (bind (sock, (struct sockaddr *) &name, sizeof (name)) == -1) {
        perror("bind");
        return -1;
    }      
    
    if (listen(sock, 10) == -1) {
        perror("listen");
        return -1;
    }

    return sock;  
}

int do_recv(int sock, void *buf, int n) {
    struct sockaddr sa;
    struct sctp_sndrcvinfo info;
    int slen, flags;
    slen = sizeof(sa);
    
    n = sctp_recvmsg(sock, buf, n, &sa, &slen, &info, &flags);
//    n = sctp_recvmsg(sock, buf, n, &sa, &slen, &info, &flags);
    if (n == -1) {
        perror("recv");    
    }
    return n;
}

int do_send(int sock, adr_t *adr, void *buf, int n) {
    
    n = sctp_sendmsg(sock, buf, n, &adr->sockadr, adr->len, 666, MSG_ADDR_OVER, 0, 0, 444);
    if (n == -1) {
        perror("send");    
    }
    return n;
}


int main(int argc, char *argv[]) {
    int i, n, cnt, pid, dest;
    int lsock;
    char data, id, rank;
    int port = 11100;
    uint64_t t0, t1;
        
    /* # processes */
    cnt = atoi(argv[1]);
    
    /* # messages */
    n = atoi(argv[2]);

    {
        adr_t dests[cnt];
           
        /* Create processes */
        rank = 0;
        for (i=1; i<cnt; i++) {
            pid = fork();
            if (pid == 0) {
                rank=cnt-i;
                break;    
            }
        }

        /* Setup connections */
        lsock = init_listen(port+rank);

        
        sleep(2); /* "Ensure" that all processes are listening, HACK!!! */
                
        
        for (i=0; i<cnt; i++) {
            get_adr(dests+i, port+i);
        }
                
        srandom(rank);        
        /* Write startup messages */
        if (rank < n) {
            do_send(lsock, &dests[(rank+1)%cnt], &data, 1);
        }
        
        sleep(1);
        
        /* Receive and forward messages to random destinations */
        while (1) {
            do_recv(lsock, &data, 1);

            dest = random()%cnt;
                    
            /* Do not send to self */           
            if (dest == rank) {
                dest = (dest+1)%cnt;    
            }
            
            do_send(lsock, &dests[dest], &data, 1);
        }
    }    
    return 0;
}

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux