lkml.org 
[lkml]   [2005]   [May]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectRe: Issues with INET sockets through loopback (lo)
Date
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;
}
\
 
 \ /
  Last update: 2005-05-31 20:51    [from the cache]
©2003-2011 Jasper Spaans