Log In
New Account
  
 
Home My Page Project Tree Code Snippets Project Openings NUTSS
 
 
Summary Tracker Lists CVS Files
 

CVS | Administration

Annotation of libnutss/examples/nutssping.c, revision 1.1

1.1     ! saikat      1: #include <stdio.h>
        !             2: #include <stdlib.h>
        !             3: #include <string.h>
        !             4: #include <time.h>
        !             5: #include <pthread.h>
        !             6:
        !             7: #ifdef LINUX
        !             8: #include <unistd.h>
        !             9: #include <fcntl.h>
        !            10: #include <sys/time.h>
        !            11: #define closesocket(x)   close((x))
        !            12: #endif
        !            13:
        !            14: #ifdef WIN32
        !            15: #include <winsock2.h>
        !            16: #define sleep(X) Sleep((X)*1000)
        !            17: #define snprintf _snprintf
        !            18:
        !            19: int gettimeofday(struct timeval * tp, void * tzp)
        !            20: {
        !            21:       time((time_t *)&tp->tv_sec);
        !            22:       tp ->tv_usec = (GetTickCount() % 1000)*1000;
        !            23:       return 0;
        !            24: }
        !            25: #endif
        !            26:
        !            27: #define _GNU_SOURCE
        !            28: #include "getopt.h"
        !            29: #include "nutss.h"
        !            30:
        !            31: #define DEFAULT_NUM_CONNECTIONS -1
        !            32: #define DEFAULT_NUM_PACKETS      1
        !            33: #define DEFAULT_INTERVAL         1
        !            34:
        !            35: #ifndef timersub
        !            36: #define timersub(tvp, uvp, vvp)                                         \
        !            37:         do {                                                            \
        !            38:                 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;          \
        !            39:                 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;       \
        !            40:                 if ((vvp)->tv_usec < 0) {                               \
        !            41:                         (vvp)->tv_sec--;                                \
        !            42:                         (vvp)->tv_usec += 1000000;                      \
        !            43:                 }                                                       \
        !            44:         } while (0)
        !            45: #endif
        !            46:
        !            47: typedef struct config {
        !            48:     int transmit;                        // Client side
        !            49:     int respond;                         // Server side
        !            50:     int num_conn;                        // Number of connections (-1 for infinite)
        !            51:     int num_pkts;                        // Number of probes per connection
        !            52:     int interval;                        // Interval between packets
        !            53:     int non_blocking;                    // Use non-blocking sockets
        !            54:     int pthreads;                        // Use threads for multiple clients
        !            55:     int select;                          // Use select for multiple clients
        !            56:     struct sockaddr_ns local, remote;    // Local and remote addresses
        !            57: } config_t;
        !            58:
        !            59: int set_nonblocking(SOCKET);
        !            60: void usage(void);
        !            61: void init(int, char **, config_t *);
        !            62: void *respond_worker(void *);
        !            63: void respond(config_t *);
        !            64: void transmit(config_t *);
        !            65:
        !            66: int
        !            67: set_nonblocking(SOCKET fd)
        !            68: {
        !            69: #ifdef WIN32
        !            70:     static int one = 1;
        !            71:       return ioctlsocket(fd, FIONBIO, (unsigned long *) &one);
        !            72: #endif
        !            73:
        !            74: #ifdef LINUX
        !            75:     int fl = fcntl(fd, F_GETFL, 0);
        !            76:     if (fl != -1)
        !            77:         return fcntl(fd, F_SETFL, fl | O_NONBLOCK);
        !            78:     return -1;
        !            79: #endif
        !            80: }
        !            81:
        !            82: void
        !            83: usage(void)
        !            84: {
        !            85:     printf("Usage:\n"
        !            86:         "  nutssping -r [-l uri] [options]\n"
        !            87:         "  nutssping -t [-l src] [options] dst \n"
        !            88:         "\n"
        !            89:         "  --transmit,-t        Send ping requests\n"
        !            90:         "  --respond,-r         Respond to ping requests\n"
        !            91:         "  --local,-l uri       Local name to use\n"
        !            92:         "                       URIs of the form user@domain\n"
        !            93:         "\n"
        !            94:         "Transmitter Options:\n"
        !            95:         "  --count,c num             Stop after num pings\n"
        !            96:         "  --use-non-blocking        Use non-blocking connect\n"
        !            97:         "\n"
        !            98:         "Responder Options:\n"
        !            99:         "  --use-pthreads            Use pthreads for multiple clients\n"
        !           100:         "  --use-select              Use select for multiple clients (not implemented)\n"
        !           101:         "\n"
        !           102:         "  --tls,s cert.pem          Enable TLS negotiation (currently ignored)\n"
        !           103:         "  --stunt,u                 Enable STUNT NAT Traversal (currently ignored)\n"
        !           104:         "  --turn,n                  Enable TURN Relay NAT Traversal (currently ignored)\n"
        !           105:         "\n"
        !           106:         "  --registrar server:port   Use sip registrar at server\n"
        !           107:         "  --password pass           Use password for registering with proxy\n"
        !           108:         );
        !           109:     exit(1);
        !           110: }
        !           111:
        !           112: void
        !           113: init(int argc, char **argv, config_t *cfg)
        !           114: {
        !           115:     int c, one = 1, zero = 0;
        !           116:     int digit_optind = 0;
        !           117:     static struct option long_options[] = {
        !           118:         {"transmit", 0, 0, 't'},
        !           119:         {"respond", 0, 0, 'r'},
        !           120:         {"local", 1, 0, 'l'},
        !           121:         {"tls", 1, 0, 's'},
        !           122:         {"stunt", 0, 0, 'u'},
        !           123:         {"turn", 0, 0, 'n'},
        !           124:         {"count", 1, 0, 'c'},
        !           125:         {"registrar", 1, 0, 0},
        !           126:         {"password", 1, 0, 0},
        !           127:         {"use-non-blocking", 0, 0, 0},
        !           128:         {"use-pthreads", 0, 0, 0},
        !           129:         {"use-sekect", 0, 0, 0},
        !           130:         {"help", 0, 0, 'h'},
        !           131:         {0, 0, 0, 0}
        !           132:     };
        !           133:
        !           134:     memset(cfg, 0, sizeof(*cfg));
        !           135:     cfg->num_conn = DEFAULT_NUM_CONNECTIONS;
        !           136:     cfg->num_pkts = DEFAULT_NUM_PACKETS;
        !           137:     cfg->interval = DEFAULT_INTERVAL;
        !           138:
        !           139:     while (1) {
        !           140:         int this_option_optind = optind ? optind : 1;
        !           141:         int option_index = 0;
        !           142:
        !           143:         c = getopt_long (argc, argv, "c:trl:s:unh", long_options, &option_index);
        !           144:         if (c == -1)
        !           145:             break;
        !           146:
        !           147:         switch (c) {
        !           148:             case 't':
        !           149:                 cfg->transmit = 1;
        !           150:                 break;
        !           151:             case 'r':
        !           152:                 cfg->respond = 1;
        !           153:                 break;
        !           154:             case 'c':
        !           155:                 cfg->num_conn = atoi(optarg);
        !           156:                 break;
        !           157:             case 'l':
        !           158:                 if (inet_uton(&cfg->local, optarg)) {
        !           159:                     if (strlen(cfg->local.user)) {
        !           160:                         nutss_config_set(NUTSS_CONFIG_USERNAME, cfg->local.user,
        !           161:                             sizeof(cfg->local.user));
        !           162:                         nutss_config_set(NUTSS_CONFIG_PROXYUSERNAME, cfg->local.user,
        !           163:                             sizeof(cfg->local.user));
        !           164:                     }
        !           165:                     if (strlen(cfg->local.domain))
        !           166:                         nutss_config_set(NUTSS_CONFIG_DOMAINNAME, cfg->local.domain,
        !           167:                             sizeof(cfg->local.domain));
        !           168:                 }
        !           169:                 break;
        !           170:             case 's':
        !           171:                 nutss_config_set(NUTSS_CONFIG_OPT_SECURE, &one, sizeof(one));
        !           172:                 break;
        !           173:             case 'u':
        !           174:                 nutss_config_set(NUTSS_CONFIG_OPT_STUNT, &one, sizeof(one));
        !           175:                 break;
        !           176:             case 'n':
        !           177:                 nutss_config_set(NUTSS_CONFIG_OPT_TURN, &one, sizeof(one));
        !           178:                 break;
        !           179:             case 0:
        !           180:                 if (!strcmp(long_options[option_index].name, "registrar")) {
        !           181:                     nutss_config_set(NUTSS_CONFIG_SIGPROXY, optarg, strlen(optarg) + 1);
        !           182:                 } else if (!strcmp(long_options[option_index].name, "password")) {
        !           183:                     nutss_config_set(NUTSS_CONFIG_PROXYPASSWORD, optarg, strlen(optarg) + 1);
        !           184:                 } else if (!strcmp(long_options[option_index].name, "use-non-blocking")) {
        !           185:                     cfg->non_blocking = 1;
        !           186:                 } else if (!strcmp(long_options[option_index].name, "pthreads")) {
        !           187:                     cfg->pthreads = 1;
        !           188:                 } else if (!strcmp(long_options[option_index].name, "select")) {
        !           189:                     cfg->select = 1;
        !           190:                     usage(); // not-implemented
        !           191:                 } else {
        !           192:                     usage();
        !           193:                 }
        !           194:                 break;
        !           195:             default:
        !           196:                 usage();
        !           197:         }
        !           198:     }
        !           199:
        !           200:     if (cfg->transmit) {
        !           201:         if (optind >= argc)
        !           202:             usage();
        !           203:         inet_uton(&cfg->remote, argv[optind++]);
        !           204:     }
        !           205:
        !           206:     if (optind < argc || !(cfg->transmit || cfg->respond))
        !           207:         usage();
        !           208:
        !           209:     cfg->local.family = AF_NUTSS;
        !           210:     if (cfg->respond && !strlen(cfg->local.service))
        !           211:         strncpy(cfg->local.service, "nutssping", sizeof(cfg->local.service));
        !           212:     if (cfg->transmit && !strlen(cfg->remote.service))
        !           213:         strncpy(cfg->remote.service, "nutssping", sizeof(cfg->remote.service));
        !           214: }
        !           215:
        !           216: void *
        !           217: respond_worker(void *arg)
        !           218: {
        !           219:     SOCKET c = (SOCKET) arg;
        !           220:     char buf[255], uri[255];
        !           221:     struct sockaddr_ns peer;
        !           222:     socklen_t lpeer = sizeof(peer);
        !           223:     int l;
        !           224:
        !           225:     memset(buf, 0, sizeof(buf));
        !           226:     nutss_getpeername(c, (struct sockaddr *)&peer, &lpeer);
        !           227:     inet_ntou(AF_NUTSS, &peer, uri, sizeof(uri));
        !           228:     for (;;) {
        !           229:         if ((l = recv(c, buf, sizeof(buf), 0)) <= 0) {
        !           230:             if (l) perror("recv");
        !           231:             break;
        !           232:         }
        !           233:         if ((l = send(c, buf, l, 0)) <= 0) {
        !           234:             if (l) perror("send");
        !           235:             break;
        !           236:         }
        !           237:         printf("%d bytes from %s: %s\n", l, uri, buf);
        !           238:     }
        !           239:     closesocket(c);
        !           240:     // printf("Closed connection from %s\n", uri);
        !           241:
        !           242:     return NULL;
        !           243: }
        !           244:
        !           245:
        !           246: void
        !           247: respond(config_t *cfg)
        !           248: {
        !           249:     char uri[255];
        !           250:     struct sockaddr_ns peer;
        !           251:     socklen_t lpeer = sizeof(peer);
        !           252:     pthread_attr_t attr;
        !           253:     pthread_t tid;
        !           254:     SOCKET s, c;
        !           255:
        !           256:     if (cfg->pthreads) {
        !           257:         pthread_attr_init(&attr);
        !           258:         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        !           259:     }
        !           260:
        !           261:     s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        !           262:     nutss_bind(s, (struct sockaddr *)&cfg->local, sizeof(cfg->local));
        !           263:     listen(s, 10);
        !           264:
        !           265:     for (;;) {
        !           266:         c = nutss_accept(s, (struct sockaddr *) &peer, &lpeer);
        !           267:         inet_ntou(AF_NUTSS, &peer, uri, sizeof(uri));
        !           268:         // printf("Accepted connection from %s\n", uri);
        !           269:         if (cfg->pthreads) {
        !           270:             if (pthread_create(&tid, &attr, respond_worker, (void *)c))
        !           271:                 closesocket(c);
        !           272:         } else if (cfg->select) {
        !           273:             // Not implemented
        !           274:             closesocket(c);
        !           275:         } else {
        !           276:             respond_worker((void *)c);
        !           277:         }
        !           278:     }
        !           279: }
        !           280:
        !           281: void
        !           282: transmit(config_t *cfg)
        !           283: {
        !           284:     struct timeval c_st, c_ok, c_rp;
        !           285:     struct timeval p_st, p_en;
        !           286:     int bytes;
        !           287:     char buf[255], uri[255];
        !           288:     struct sockaddr_ns peer;
        !           289:     socklen_t lpeer = sizeof(peer);
        !           290:     SOCKET s;
        !           291:     int conn, mconn, seq, mseq, l;
        !           292:     fd_set fds, _fds;
        !           293:
        !           294:     memset(buf, 0, 255);
        !           295:     memset(uri, 0, 255);
        !           296:     conn = 0;
        !           297:     mconn = cfg->num_conn;
        !           298:     while (mconn == -1 || mconn-- > 0) {
        !           299:         if (conn) sleep(cfg->interval);
        !           300:
        !           301:         gettimeofday(&c_st, NULL);
        !           302:         conn++;
        !           303:         seq = 0;
        !           304:         bytes = 0;
        !           305:
        !           306:         s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        !           307:         if (cfg->non_blocking) {
        !           308:             set_nonblocking(s);
        !           309:             FD_ZERO(&fds);
        !           310:             FD_SET(s, &fds);
        !           311:         }
        !           312:         if (nutss_connect(s, (struct sockaddr *)&cfg->remote, sizeof(cfg->remote)) != 0) {
        !           313:             perror("connect");
        !           314:             closesocket(s);
        !           315:             continue;
        !           316:         }
        !           317:
        !           318:         gettimeofday(&c_ok, NULL);
        !           319:         timersub(&c_ok, &c_st, &c_ok);
        !           320:
        !           321:         nutss_getpeername(s, (struct sockaddr *)&peer, &lpeer);
        !           322:         inet_ntou(AF_NUTSS, &peer, uri, sizeof(uri));
        !           323:         mseq = cfg->num_pkts;
        !           324:         while (mseq == -1 || mseq-- > 0) {
        !           325:             if (seq) sleep(cfg->interval);
        !           326:
        !           327:             snprintf(buf, sizeof(buf), "seq=%d.%d", conn, ++seq);
        !           328:             gettimeofday(&p_st, NULL);
        !           329:             if (cfg->non_blocking) {
        !           330:                 _fds = fds;
        !           331:                 if (select(s+1, NULL, &_fds, NULL, NULL) != 1) {
        !           332:                     perror("select");
        !           333:                     break;
        !           334:                 }
        !           335:             }
        !           336:             if (send(s, buf, strlen(buf), 0) != strlen(buf)) {
        !           337:                 perror("send");
        !           338:                 break;
        !           339:             }
        !           340:             if (cfg->non_blocking) {
        !           341:                 _fds = fds;
        !           342:                 if (select(s+1, &_fds, NULL, NULL, NULL) != 1) {
        !           343:                     perror("select");
        !           344:                     break;
        !           345:                 }
        !           346:             }
        !           347:             if ((l = recv(s, buf, sizeof(buf), 0)) <= 0) {
        !           348:                 perror("recv");
        !           349:                 break;
        !           350:             }
        !           351:             gettimeofday(&p_en, NULL);
        !           352:             if (seq == 1) {
        !           353:                 c_rp = p_en;
        !           354:                 timersub(&c_rp, &c_st, &c_rp);
        !           355:             }
        !           356:             bytes += l;
        !           357:             timersub(&p_en, &p_st, &p_en);
        !           358:             printf("%d bytes from %s: %s crtt0=%5.3fms crtt1=%5.3fms rtt%d=%5.3f ms\n", l, uri,
        !           359:                    buf,
        !           360:                    c_ok.tv_sec*1000 + c_ok.tv_usec/1000.0,
        !           361:                    c_rp.tv_sec*1000 + c_rp.tv_usec/1000.0,
        !           362:                    seq,
        !           363:                    p_en.tv_sec*1000 + p_en.tv_usec/1000.0);
        !           364:         }
        !           365:
        !           366:         closesocket(s);
        !           367:     }
        !           368: }
        !           369:
        !           370: int
        !           371: main(int argc, char **argv)
        !           372: {
        !           373:     config_t cfg;
        !           374:
        !           375:     init(argc, argv, &cfg);
        !           376:
        !           377:     nutss_init();
        !           378:
        !           379:     if (cfg.respond)
        !           380:         respond(&cfg);
        !           381:
        !           382:     if (cfg.transmit)
        !           383:         transmit(&cfg);
        !           384:
        !           385:     exit(0);
        !           386: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
 

GForge.cis.cornell.edu is brought to you by

Cornell Computing and Information Science


Powered By GForge Collaborative Development Environment