SCTP Discussions

Text archives Help


[SCTP-Discussion] Re: PD: echo client problem - ERROR: SocketAddress::createSocketAddress(sockaddr) - Unknown address family 1023!


Chronological Thread 
  • From: Thomas Dreibholz <dreibh AT exp-math.uni-essen.de>
  • To: "Przemek J." <przemekj AT simplusnet.pl>
  • Cc: discussion AT sctp.de
  • Subject: [SCTP-Discussion] Re: PD: echo client problem - ERROR: SocketAddress::createSocketAddress(sockaddr) - Unknown address family 1023!
  • Date: Wed Feb 12 09:52:00 2003
  • List-id: SCTP Discussions <discussion.sctp.de>
  • Organization: University of Essen, Institute for Experimental Mathematics

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am Dienstag, 11. Februar 2003 19:23 schrieb P J:
> ----- Original Message -----
> From: Przemek J.
> <przemekj AT simplusnet.pl>
> To:
> <discussion AT sctp.de>
> Sent: Tuesday, February 11, 2003 6:30 PM
> Subject: echo client problem - ERROR:
> SocketAddress::createSocketAddress(sockaddr) - Unknown address family 1023!
>
> > I have running echo server on port 7 on localhost. It works ok with
> > sctpterminal, on many streams.
> >
> > I have written client, which will connect on given stream to this server,
> > send data and receive it back (echoed by the server), but when i execute
>
> it,
>
> > it displays error messages:
> >
> > ERROR: SocketAddress::createSocketAddress(sockaddr) - Unknown address
>
> family
>
> > 1023!
> > sendmsg: Cannot assign requested address
> >
> > What is wrong with my code?


> > static void
> > echo(int fd, int socketModeUDP)
> > {
...
> > /* Set up the msghdr structure */
> > memset(msg, 0, sizeof (*msg));
> > msg->msg_name=&fd; /* ptr to socket address structure */
> > msg->msg_namelen=sizeof(fd);

As you have already said in your comment, msg->msg_name has to be a pointer
to
a sockaddr structure. fd is a file descriptor, I assume it is 1023. The
socket API interprets this as sockaddr's sa_family -> 1023 is not AF_INET,
AF_INET6, etc. -> error.

Set msg->msg_name to the correct pointer and msg->msg_namelen to the
structure
length.


Attached to this mail, you find a modified TCP_combined_server, providing a
multiple-streams echo/discard combination. This source should help you using
the msghdr structures.


Best regards
- --
=======================================================================
Dipl.-Inform. Thomas Dreibholz

University of Essen, Room ES210
Inst. for Experimental Mathematics Ellernstraße 29
Computer Networking Technology Group D-45326 Essen/Germany
- -----------------------------------------------------------------------
E-Mail:
dreibh AT exp-math.uni-essen.de
Homepage: http://www.exp-math.uni-essen.de/~dreibh
=======================================================================
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQE+SgnO32BbsHYPLWURAqrAAKCj04cmgoeTIpFXkFh6f4oYd61iIwCeIRaZ
7UDwVIqH1kaZKzOLjtIPQGM=
=c0Q9
-----END PGP SIGNATURE-----
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <ext_socket.h>
#include <net/route.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>


#define ECHO_PORT         7
#define DISCARD_PORT      9
#define DAYTIME_PORT     13
#define CHARGEN_PORT     19
#define ECHODISCARD_PORT  8

#define SECONDS_TO_CLEANUP 5
#define BUFFER_SIZE 1024
#define MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES    1 /* do not change this */

static int verbose  = 0;
static int vverbose = 0;
static int tooManyAddresses = 0;
static int unknownCommand = 0;
static struct sockaddr_in local_addr[MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES];
static unsigned short noOfLocalAddresses = 0;

struct server_data {
    int fd;
    void * (* connection_handler)(void *);
};



void printUsage(void)
{
    printf("Usage:   combined_server [options]\n");
    printf("options:\n");
    printf("-s       source address\n");
    printf("-v       verbose mode\n");   
    printf("-V       very verbose mode\n");
}

void getArgs(int argc, char **argv)
{
    int c;
    extern char *optarg;
/*  extern int optind;*/

    while ((c = getopt(argc, argv, "hs:vV")) != -1)
    {
        switch (c) {
        case 'h':
            printUsage();
            exit(0);
        case 's':
            if (noOfLocalAddresses < MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES) {
                    bzero(&local_addr[noOfLocalAddresses], sizeof(local_addr[0]));
#if !defined (LINUX)
                    local_addr[noOfLocalAddresses].sin_len    = sizeof(local_addr[0]);
#endif
                    local_addr[noOfLocalAddresses].sin_family = AF_INET;
                    if (inet_aton(optarg, &(local_addr[noOfLocalAddresses].sin_addr)) == 1) {
                        noOfLocalAddresses++;
                    }
            } else {
                tooManyAddresses = 1;
            }
            break;
        case 'v':
            verbose = 1;
            break;
        case 'V':
            verbose = 1;
            vverbose = 1;
            break;
        default:
            unknownCommand = 1;
            break;
       }
    }
}

void checkArgs(void)
{
    int abortProgram;
    int printUsageInfo;
    
    abortProgram = 0;
    printUsageInfo = 0;
    
    if (noOfLocalAddresses == 0) {
      bzero(&local_addr[noOfLocalAddresses], sizeof(local_addr[0]));    
#if !defined (LINUX)
      local_addr[noOfLocalAddresses].sin_len    = sizeof(local_addr[0]);
#endif
      local_addr[noOfLocalAddresses].sin_family = AF_INET;
      inet_aton("0.0.0.0", &(local_addr[noOfLocalAddresses].sin_addr));
      noOfLocalAddresses = 1;
    }
    if (tooManyAddresses == 1) {
        printf("Error:   Too many source addresses were specified. Taking only the %d first ones.\n",
               MAXIMUM_NUMBER_OF_LOCAL_ADDRESSES);
    }
    if (unknownCommand ==1) {
         printf("Error:   Unkown options in command.\n");
         printUsageInfo = 1;
    }
    
    if (printUsageInfo == 1)
        printUsage();
    if (abortProgram == 1)
        exit(-1);
}

static void*
handle_chargen(void *arg)
{
    int fd;
    int n, length;
    char buffer[BUFFER_SIZE];

    fd = *((int *) arg);
    free(arg);
    
    pthread_detach(pthread_self());
    
    length = 1 + (random() % 512);
    memset(buffer, 'A', length);
    buffer[length-1] = '\n';

    while ((n=ext_write(fd, buffer, length)) >  0){
        if (vverbose) {
            printf("%-6d: sending %u bytes.\n", fd, n);
            fflush(stdout);
        }
        if (n != ext_write(fd, buffer, n)) {
            printf("%-6d: Writing %u bytes failed.\n", fd, n);
        }
        length = 1 + (random() % 512);
        memset(buffer, 'A', length);
        buffer[length-1] = '\n';
    }
    ext_close(fd);
    if (verbose) {
        printf("%-6d: Connection closed.\n", fd);
        fflush(stdout);
    }
    return(NULL);
}

static void*
handle_discard(void *arg)
{
    int fd;
    int n;
    char buffer[BUFFER_SIZE];
    
    fd = *((int *) arg);
    free(arg);

    pthread_detach(pthread_self());
        
    while ((n=ext_read(fd, buffer, sizeof(buffer))) >  0){
        if (vverbose) {
            printf("%-6d: Discarding %u bytes.\n", fd, n);
            fflush(stdout);
        }
    }
    
    ext_close(fd);
    if (verbose) {
        printf("%-6d: Connection closed.\n", fd);
        fflush(stdout);
    }
    return(NULL);
}

static void*
handle_echo(void *arg)
{
    int fd;
    int n;
    char buffer[BUFFER_SIZE];

    fd = *((int *) arg);
    free(arg);

    pthread_detach(pthread_self());

    while ((n=ext_read(fd, buffer, sizeof(buffer))) >  0){
        if (vverbose) {
            printf("%-6d: Echoing %u bytes.\n", fd, n);
            fflush(stdout);
        }
        if (n != ext_write(fd, buffer, n)) {
            printf("%-6d: Writing %u bytes failed.\n", fd, n);
        }
    }
    ext_close(fd);
    if (verbose) {
        printf("%-6d: Connection closed.\n", fd);
        fflush(stdout);
    }
    return(NULL);
}

static void*
handle_echodiscard(void *arg)
{
    int                         fd;
    int                         n;
    char                        buffer[BUFFER_SIZE];
    char                        cbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
    unsigned short              streamID;
    unsigned int                protoID;
    unsigned int                inStreams;
    unsigned int                outStreams;
    struct sctp_event_subscribe events;
    union sctp_notification*    notification;
    struct sctp_assoc_change*   sac;
    struct sctp_sndrcvinfo*     info;
    struct iovec                iov;
    struct msghdr               msg;
    struct cmsghdr*             cmsg;

    inStreams  = 1;
    outStreams = 1;

    fd = *((int *) arg);
    free(arg);

    pthread_detach(pthread_self());

    bzero((char*)&events,sizeof(events));
    events.sctp_data_io_event     = 1;
    events.sctp_association_event = 1;
    if(ext_setsockopt(fd, IPPROTO_SCTP, SCTP_SET_EVENTS, &events, sizeof(events)) < 0)
       perror("setsockopt for SCTP_SET_EVENTS failed");

    for(;;) {
        iov.iov_base       = &buffer;
        iov.iov_len        = sizeof(buffer);
        msg.msg_name       = NULL;
        msg.msg_namelen    = 0;
        msg.msg_control    = &cbuf;
        msg.msg_controllen = sizeof(cbuf);
        msg.msg_iov        = &iov;
        msg.msg_iovlen     = 1;
        msg.msg_flags      = 0;

        n = ext_recvmsg(fd, &msg, 0);
        if(n <= 0) {
            break;
        }

        if(msg.msg_flags & MSG_NOTIFICATION) {
            notification = (union sctp_notification*)&buffer;
            if(notification->h.sn_type == SCTP_ASSOC_CHANGE) {
               sac = &notification->sn_assoc_change;
               inStreams  = sac->sac_inbound_streams;
               outStreams = sac->sac_outbound_streams;
               if (verbose) {
                  printf("%-6d: AssocChange event: in=%u out=%u.\n", fd, inStreams, outStreams);
               }
            }
        }
        else {
            streamID = 0;
            protoID  = 0;
            if(msg.msg_controllen > 0) {
               cmsg = CMSG_FIRSTHDR(&msg);
               if(cmsg != NULL) {
                  while(cmsg != NULL) {
                     if((cmsg->cmsg_level == IPPROTO_SCTP) &&
                        (cmsg->cmsg_type  == SCTP_SNDRCV)) {
                        info     = (struct sctp_sndrcvinfo*)CMSG_DATA(cmsg);
                        streamID = info->sinfo_stream;
                        protoID  = info->sinfo_ppid;
                     }
                     cmsg = CMSG_NXTHDR(&msg,cmsg);
                  }
               }
            }

            if (vverbose) {
                printf("%-6d: Received %u bytes, stream #%u, PPID $%08x.\n", fd, n, streamID, protoID);
                fflush(stdout);
            }
            if((streamID % 2) == 0) {
               iov.iov_base       = &buffer;
               iov.iov_len        = n;
               msg.msg_name       = NULL;
               msg.msg_namelen    = 0;
               msg.msg_control    = &cbuf;
               msg.msg_controllen = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
               msg.msg_iov        = &iov;
               msg.msg_iovlen     = 1;
               msg.msg_flags      = 0;

               cmsg = (struct cmsghdr*)&cbuf;
               cmsg->cmsg_level = IPPROTO_SCTP;
               cmsg->cmsg_type  = SCTP_SNDRCV;
               cmsg->cmsg_len   = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));

               info                   = (struct sctp_sndrcvinfo*)CMSG_DATA(cmsg);
               info->sinfo_assoc_id   = 0;
               info->sinfo_flags      = 0;
               info->sinfo_stream     = streamID % outStreams;
               info->sinfo_ppid       = protoID;
               info->sinfo_timetolive = (unsigned int)-1;

               if (vverbose) {
                   printf("%-6d: Echoing %u bytes via stream #%u.\n", fd, n, info->sinfo_stream);
               }
               if (n != ext_sendmsg(fd, &msg, n)) {
                   printf("%-6d: Writing %u bytes failed.\n", fd, n);
               }
            }
            else {
               if (vverbose) {
                  printf("%-6d: Discarding %u bytes.\n", fd, n);
               }
            }
        }
    }
    ext_close(fd);
    if (verbose) {
        printf("%-6d: Connection closed.\n", fd);
        fflush(stdout);
    }
    return(NULL);
}

static void*
handle_daytime(void *arg)
{
    int fd;
    int timeAsStringLen;
    char *timeAsString;
    time_t now;

    fd = *((int *) arg);
    free(arg);

    pthread_detach(pthread_self());
    
    time(&now);
    timeAsString = ctime(&now);
    timeAsStringLen = strlen(timeAsString);
    
    if (timeAsStringLen != ext_write(fd, timeAsString, timeAsStringLen)) {
            printf("%-6d: Writing the daytime failed.\n", fd);
    }
    if (vverbose) {
        printf("%-6d: Daytime sent back: %s", fd, timeAsString);
        fflush(stdout);
    }

    ext_close(fd);
    if (verbose) {
        printf("%-6d: Connection closed.\n", fd);
        fflush(stdout);
    }
    return(NULL);
}

static void*
start_server(void *arg)
{
    pthread_t tid;
    int *fdp;
    struct sockaddr_in remote_addr;
    int remote_addr_len;
    struct server_data data;

    data = *((struct server_data *) arg);
    free(arg);

    bzero(&remote_addr, sizeof(remote_addr));
    remote_addr_len = sizeof(remote_addr);
    for(;;){
        fdp = malloc(sizeof(int));
        if((*fdp=ext_accept(data.fd, (struct sockaddr *) &remote_addr, &remote_addr_len)) < 0)
            perror("accept call failed");
        if (verbose) {
            printf("%-6d: Connection accepted from %s:%u.\n", *fdp, inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port));
            fflush(stdout);
        }
        pthread_create(&tid, NULL, data.connection_handler, fdp);
    }
    return(NULL);
}

static pthread_t
init_server(struct sockaddr_in local_addr, int port, void *(connection_handler ()))
{
    pthread_t                   tid;
    int                         fd;
    struct sctp_initmsg         initmsg;
    struct sctp_event_subscribe events;
    struct server_data          *server_data_p;

    if ((fd = ext_socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0)
        perror("socket call failed");

    initmsg.sinit_num_ostreams   = 16;
    initmsg.sinit_max_instreams  = 16;
    initmsg.sinit_max_attempts   = 5;
    initmsg.sinit_max_init_timeo = 10000;
    if(ext_setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, (char*)&initmsg, sizeof(initmsg)) < 0)
       perror("setsockopt for SCTP_INITMSG failed");

    bzero((char*)&events,sizeof(events));
    events.sctp_data_io_event     = 1;
    events.sctp_association_event = 1;
    if(ext_setsockopt(fd, IPPROTO_SCTP, SCTP_SET_EVENTS, &events, sizeof(events)) < 0)
       perror("setsockopt for SCTP_SET_EVENTS failed");

    local_addr.sin_port= htons(port);
    if(ext_bind(fd, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0)
        perror("bind call failed");

    if(ext_listen(fd, 0) < 0)
        perror("listen call failed");

    server_data_p = malloc(sizeof(struct server_data));
    server_data_p->fd = fd;
    server_data_p->connection_handler = connection_handler;
    if (verbose) {
        printf("Starting server on port %u.\n", port);
        fflush(stdout);
    }
    pthread_create(&tid, NULL, &start_server, (void *)server_data_p);
    return(tid);
}

int main (int argc, char * argv[])
{
    pthread_t echo_tid, discard_tid, daytime_tid, chargen_tid, echodiscard_tid;

    getArgs(argc, argv);
    checkArgs();
      
    echo_tid        = init_server(local_addr[0], ECHO_PORT,    &handle_echo);
    discard_tid     = init_server(local_addr[0], DISCARD_PORT, &handle_discard);
    daytime_tid     = init_server(local_addr[0], DAYTIME_PORT, &handle_daytime);
    chargen_tid     = init_server(local_addr[0], CHARGEN_PORT,     &handle_chargen);
    echodiscard_tid = init_server(local_addr[0], ECHODISCARD_PORT, &handle_echodiscard);

    pthread_join(echo_tid, NULL);
    pthread_join(discard_tid, NULL);
    pthread_join(daytime_tid, NULL);
    pthread_join(chargen_tid, NULL);
    pthread_join(echodiscard_tid, NULL);

    printf("Give the SCTP thread time to clean up ...");
    fflush(stdout);
    sleep(SECONDS_TO_CLEANUP);
    printf(" the time is over now!\n");
    return 0;
}


  • [SCTP-Discussion] Re: PD: echo client problem - ERROR: SocketAddress::createSocketAddress(sockaddr) - Unknown address family 1023!, Thomas Dreibholz, 02/12/2003

Archive powered by MHonArc 2.6.19+.

Top of page