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.2

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));
1.2     ! saikat    323:         printf("0 bytes from %s: seq=%d.0 time=%5.3f ms\n", uri, conn,
        !           324:                buf, c_ok.tv_sec*1000 + c_ok.tv_usec/1000.0);
        !           325:
1.1       saikat    326:         mseq = cfg->num_pkts;
                    327:         while (mseq == -1 || mseq-- > 0) {
                    328:             if (seq) sleep(cfg->interval);
                    329:
                    330:             snprintf(buf, sizeof(buf), "seq=%d.%d", conn, ++seq);
                    331:             gettimeofday(&p_st, NULL);
                    332:             if (cfg->non_blocking) {
                    333:                 _fds = fds;
                    334:                 if (select(s+1, NULL, &_fds, NULL, NULL) != 1) {
                    335:                     perror("select");
                    336:                     break;
                    337:                 }
                    338:             }
                    339:             if (send(s, buf, strlen(buf), 0) != strlen(buf)) {
                    340:                 perror("send");
                    341:                 break;
                    342:             }
                    343:             if (cfg->non_blocking) {
                    344:                 _fds = fds;
                    345:                 if (select(s+1, &_fds, NULL, NULL, NULL) != 1) {
                    346:                     perror("select");
                    347:                     break;
                    348:                 }
                    349:             }
                    350:             if ((l = recv(s, buf, sizeof(buf), 0)) <= 0) {
                    351:                 perror("recv");
                    352:                 break;
                    353:             }
                    354:             gettimeofday(&p_en, NULL);
                    355:             if (seq == 1) {
                    356:                 c_rp = p_en;
                    357:                 timersub(&c_rp, &c_st, &c_rp);
                    358:             }
                    359:             bytes += l;
                    360:             timersub(&p_en, &p_st, &p_en);
1.2     ! saikat    361:             printf("%d bytes from %s: %s time=%5.3f ms\n", l, uri, buf,
1.1       saikat    362:                    p_en.tv_sec*1000 + p_en.tv_usec/1000.0);
                    363:         }
                    364:
                    365:         closesocket(s);
                    366:     }
                    367: }
                    368:
                    369: int
                    370: main(int argc, char **argv)
                    371: {
                    372:     config_t cfg;
                    373:
                    374:     init(argc, argv, &cfg);
                    375:
                    376:     nutss_init();
                    377:
                    378:     if (cfg.respond)
                    379:         respond(&cfg);
                    380:
                    381:     if (cfg.transmit)
                    382:         transmit(&cfg);
                    383:
                    384:     exit(0);
                    385: }

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