Browse code

FIX: ipv4_genport() wasn't returning the correct port on /etc/services lookups

Dario Rodriguez authored on 17/12/2015 13:47:27
Showing 1 changed files
... ...
@@ -84,7 +84,7 @@ ipv4_genport(char *portname, int fallback)
84 84
 {
85 85
         struct addrinfo hints,*ai;
86 86
         struct sockaddr_in *in;
87
-        char port;
87
+        int port;
88 88
         if(*portname>='0' && *portname<='9')
89 89
                 return(atoi(portname));
90 90
         memset(&hints,0,sizeof(hints));
... ...
@@ -95,7 +95,7 @@ ipv4_genport(char *portname, int fallback)
95 95
                 freeaddrinfo(ai),ai=NULL;
96 96
                 return(fallback);
97 97
         }
98
-        port=ntohs(in->sin_port);
98
+	port=htons(in->sin_port);
99 99
         freeaddrinfo(ai),ai=NULL;
100 100
         return(port);
101 101
 }
Browse code

socklib: add sock_setsafe

Dario Rodriguez authored on 18/05/2015 19:39:12
Showing 1 changed files
... ...
@@ -466,6 +466,19 @@ sock_setunsafe(int fd)
466 466
         setsockopt(fd,SOL_SOCKET,SO_LINGER,(void *)&ltime,sizeof(ltime));
467 467
 }
468 468
 
469
+void
470
+sock_setsafe(int fd)
471
+{
472
+        int val;
473
+        struct linger ltime;
474
+        val=0;
475
+        setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(val));
476
+        ltime.l_onoff=0;
477
+        ltime.l_linger=1;
478
+        setsockopt(fd,SOL_SOCKET,SO_LINGER,(void *)&ltime,sizeof(ltime));
479
+}
480
+
481
+
469 482
 /* local functions */
470 483
 static int
471 484
 sselect_adduserptr(_sselect *ssel, int fd, void *userptr)
Browse code

Fix the zeroing of new userptr slots in sselect_adduserptr() as it wasn't being done correctly

Dario Rodriguez authored on 23/04/2015 19:45:50
Showing 1 changed files
... ...
@@ -480,7 +480,7 @@ sselect_adduserptr(_sselect *ssel, int fd, void *userptr)
480 480
                 if((newptr=realloc(ssel->userptr,sizeof(void *)*newsize))==NULL)
481 481
                         return(-1);
482 482
                 ssel->userptr=newptr;
483
-                memset(ssel->userptr+ssel->sizeuserptr,sizeof(void *)*(newsize-ssel->sizeuserptr),0);
483
+                memset(ssel->userptr+ssel->sizeuserptr,0,sizeof(void *)*(newsize-ssel->sizeuserptr));
484 484
                 ssel->sizeuserptr=newsize;
485 485
         }
486 486
         ssel->userptr[fd]=userptr;
Browse code

socklib: add sock_readble()

Dario Rodriguez authored on 01/07/2014 09:30:17
Showing 1 changed files
... ...
@@ -231,6 +231,19 @@ sock_setblocking(int fd, int block)
231 231
         return(fcntl(fd,F_SETFL,fl));
232 232
 }
233 233
 
234
+int
235
+sock_readable(int fd) /* tests readability */
236
+{
237
+        struct timeval tv;
238
+        fd_set rset;
239
+        FILLTV(tv,0,0);
240
+        FD_ZERO(&rset);
241
+        FD_SET(fd,&rset);
242
+        if(select(fd+1,&rset,NULL,NULL,&tv)>0)
243
+                return(0);
244
+        return(-1);
245
+}
246
+
234 247
 sselect *
235 248
 sselect_init(void)
236 249
 {
Browse code

socklib: fix sselect, userptr store/retrieval

Dario Rodriguez authored on 20/06/2014 10:28:04
Showing 1 changed files
... ...
@@ -362,7 +362,7 @@ sselect_getread(sselect *paramssel, int *fds, int sizefds)
362 362
         _sselect *ssel=(_sselect *)paramssel;
363 363
         if(ssel==NULL || fds==NULL || sizefds<1)
364 364
                 return(-1);
365
-        for(n=0,i=ssel->readresultreturned;i<ssel->maxfd && n<sizefds;i++) {
365
+        for(n=0,i=ssel->readresultreturned;i<=ssel->maxfd && n<sizefds;i++) {
366 366
                 if(FD_ISSET(i,&(ssel->readresult))) {
367 367
                         fds[n++]=i;
368 368
                         FD_CLR(i,&(ssel->readresult));
... ...
@@ -379,7 +379,7 @@ sselect_getwrite(sselect *paramssel, int *fds, int sizefds)
379 379
         _sselect *ssel=(_sselect *)paramssel;
380 380
         if(ssel==NULL || fds==NULL || sizefds<1)
381 381
                 return(-1);
382
-        for(n=0,i=ssel->writeresultreturned;i<ssel->maxfd && n<sizefds;i++) {
382
+        for(n=0,i=ssel->writeresultreturned;i<=ssel->maxfd && n<sizefds;i++) {
383 383
                 if(FD_ISSET(i,&(ssel->writeresult))) {
384 384
                         fds[n++]=i;
385 385
                         FD_CLR(i,&(ssel->writeresult));
... ...
@@ -397,7 +397,7 @@ sselect_getreadfiltered(sselect *paramssel, fd_set *filter, int *fds, int sizefd
397 397
         _sselect *ssel=(_sselect *)paramssel;
398 398
         if(ssel==NULL || fds==NULL || sizefds<1)
399 399
                 return(-1);
400
-        for(n=0,i=0;i<ssel->maxfd && n<sizefds;i++) {
400
+        for(n=0,i=0;i<=ssel->maxfd && n<sizefds;i++) {
401 401
                 if(FD_ISSET(i,&(ssel->readresult)) && FD_ISSET(i,filter)) {
402 402
                         fds[n++]=i;
403 403
                         FD_CLR(i,&(ssel->readresult));
... ...
@@ -413,7 +413,7 @@ sselect_getwritefiltered(sselect *paramssel, fd_set *filter, int *fds, int sizef
413 413
         _sselect *ssel=(_sselect *)paramssel;
414 414
         if(ssel==NULL || fds==NULL || sizefds<1)
415 415
                 return(-1);
416
-        for(n=0,i=0;i<ssel->maxfd && n<sizefds;i++) {
416
+        for(n=0,i=0;i<=ssel->maxfd && n<sizefds;i++) {
417 417
                 if(FD_ISSET(i,&(ssel->writeresult)) && FD_ISSET(i,filter)) {
418 418
                         fds[n++]=i;
419 419
                         FD_CLR(i,&(ssel->writeresult));
... ...
@@ -468,6 +468,7 @@ sselect_adduserptr(_sselect *ssel, int fd, void *userptr)
468 468
                         return(-1);
469 469
                 ssel->userptr=newptr;
470 470
                 memset(ssel->userptr+ssel->sizeuserptr,sizeof(void *)*(newsize-ssel->sizeuserptr),0);
471
+                ssel->sizeuserptr=newsize;
471 472
         }
472 473
         ssel->userptr[fd]=userptr;
473 474
         return(0);
Browse code

socklib: fix ipv4_genip

Dario Rodriguez authored on 19/06/2014 16:43:52
Showing 1 changed files
... ...
@@ -65,12 +65,16 @@ ipv4_genip(char *hostname, long *resulthostsize)
65 65
         if(getaddrinfo(hostname,NULL,&hints,&ai)!=0)
66 66
                 return(NULL);
67 67
         in=(struct sockaddr_in *)ai->ai_addr;
68
-        if(in==NULL || (host=malloc(ai->ai_addrlen))==NULL) {
68
+        if(in->sin_family!=AF_INET) {
69 69
                 freeaddrinfo(ai),ai=NULL;
70 70
                 return(NULL);
71 71
         }
72
-        memcpy(host,ai->ai_addr,ai->ai_addrlen);
73
-        *resulthostsize=ai->ai_addrlen;
72
+        *resulthostsize=4;
73
+        if(in==NULL || (host=malloc(*resulthostsize))==NULL) {
74
+                freeaddrinfo(ai),ai=NULL;
75
+                return(NULL);
76
+        }
77
+        memcpy(host,&(in->sin_addr),*resulthostsize);
74 78
         freeaddrinfo(ai),ai=NULL;
75 79
         return(host);
76 80
 }
Browse code

socklib: add per-fd userptr

Dario Rodriguez authored on 12/06/2014 11:21:04
Showing 1 changed files
... ...
@@ -32,6 +32,8 @@ typedef struct _sselect {
32 32
         int sizeresult;
33 33
         int readresultreturned;
34 34
         int writeresultreturned;
35
+        int sizeuserptr;
36
+        void **userptr;
35 37
 } _sselect;
36 38
 
37 39
 
... ...
@@ -47,6 +49,11 @@ typedef struct _sselect {
47 49
                 s.sin_port=htons(port)
48 50
 #endif
49 51
 
52
+#define USERPTRBLOCKSIZE 1024
53
+
54
+static int sselect_adduserptr(_sselect *ssel, int fd, void *userptr);
55
+static int sselect_clearuserptr(_sselect *ssel, int fd);
56
+
50 57
 char *
51 58
 ipv4_genip(char *hostname, long *resulthostsize)
52 59
 {
... ...
@@ -231,6 +238,20 @@ sselect_init(void)
231 238
         return((sselect *)ssel);
232 239
 }
233 240
 
241
+void
242
+sselect_free(sselect *paramssel)
243
+{
244
+        _sselect *ssel=(_sselect *)paramssel;
245
+        if(ssel==NULL)
246
+                return;
247
+        if(ssel->userptr!=NULL) {
248
+                ssel->sizeuserptr=0;
249
+                free(ssel->userptr),ssel->userptr=NULL;
250
+        }
251
+        free(ssel),ssel=NULL;
252
+}
253
+
254
+
234 255
 int
235 256
 sselect_reset(sselect *paramssel)
236 257
 {
... ...
@@ -243,15 +264,21 @@ sselect_reset(sselect *paramssel)
243 264
         ssel->numfd=0;
244 265
         FD_ZERO(&(ssel->readresult));
245 266
         FD_ZERO(&(ssel->writeresult));
267
+        memset(ssel->userptr,0,sizeof(void *)*ssel->sizeuserptr);
246 268
         return(0);
247 269
 }
248 270
 
249 271
 int
250
-sselect_addread(sselect *paramssel, int fd)
272
+sselect_addread(sselect *paramssel, int fd, void *userptr)
251 273
 {
252 274
         _sselect *ssel=(_sselect *)paramssel;
253 275
         if(ssel==NULL || fd<0 || FD_ISSET(fd,&(ssel->readset)))
254 276
                 return(-1);
277
+        if(userptr!=NULL) {
278
+                if(sselect_adduserptr(ssel, fd, userptr)!=0)
279
+                        return(-1);
280
+        } else
281
+                sselect_clearuserptr(ssel,fd);
255 282
         FD_SET(fd,&(ssel->readset));
256 283
         if(fd>ssel->maxfd)
257 284
                 ssel->maxfd=fd;
... ...
@@ -261,11 +288,16 @@ sselect_addread(sselect *paramssel, int fd)
261 288
 
262 289
 
263 290
 int
264
-sselect_addwrite(sselect *paramssel, int fd)
291
+sselect_addwrite(sselect *paramssel, int fd, void *userptr)
265 292
 {
266 293
         _sselect *ssel=(_sselect *)paramssel;
267 294
         if(ssel==NULL || fd<0 || FD_ISSET(fd,&(ssel->writeset)))
268 295
                 return(-1);
296
+        if(userptr!=NULL) {
297
+                if(sselect_adduserptr(ssel, fd, userptr)!=0)
298
+                        return(-1);
299
+        } else
300
+                sselect_clearuserptr(ssel,fd);
269 301
         FD_SET(fd,&(ssel->writeset));
270 302
         if(fd>ssel->maxfd)
271 303
                 ssel->maxfd=fd;
... ...
@@ -386,6 +418,15 @@ sselect_getwritefiltered(sselect *paramssel, fd_set *filter, int *fds, int sizef
386 418
         return(n);
387 419
 }
388 420
 
421
+void *
422
+sselect_getuserptr(sselect *paramssel, int fd)
423
+{
424
+        _sselect *ssel=(_sselect *)paramssel;
425
+        if(ssel==NULL || fd<0 || fd>=ssel->sizeuserptr)
426
+                return(NULL);
427
+        return(ssel->userptr[fd]);
428
+}
429
+
389 430
 
390 431
 /* aux functions */
391 432
 void
... ...
@@ -408,3 +449,34 @@ sock_setunsafe(int fd)
408 449
         setsockopt(fd,SOL_SOCKET,SO_LINGER,(void *)&ltime,sizeof(ltime));
409 450
 }
410 451
 
452
+/* local functions */
453
+static int
454
+sselect_adduserptr(_sselect *ssel, int fd, void *userptr)
455
+{
456
+        if(ssel==NULL || fd<0)
457
+                return(-1);
458
+        if(ssel->sizeuserptr<(fd+1)) {
459
+                void **newptr;
460
+                int newsize;
461
+                newsize=(fd+USERPTRBLOCKSIZE)/USERPTRBLOCKSIZE;
462
+                newsize*=USERPTRBLOCKSIZE;
463
+                if((newptr=realloc(ssel->userptr,sizeof(void *)*newsize))==NULL)
464
+                        return(-1);
465
+                ssel->userptr=newptr;
466
+                memset(ssel->userptr+ssel->sizeuserptr,sizeof(void *)*(newsize-ssel->sizeuserptr),0);
467
+        }
468
+        ssel->userptr[fd]=userptr;
469
+        return(0);
470
+}
471
+
472
+static int
473
+sselect_clearuserptr(_sselect *ssel, int fd)
474
+{
475
+        if(ssel==NULL || fd<0)
476
+                return(-1);
477
+        if(ssel->sizeuserptr<(fd+1))
478
+                return(0);
479
+        ssel->userptr[fd]=NULL;
480
+        return(0);
481
+}
482
+
Browse code

socklib: add getreadfiltered()/getwritefiltered()

Dario Rodriguez authored on 11/06/2014 10:13:57
Showing 1 changed files
... ...
@@ -3,12 +3,6 @@
3 3
  *
4 4
  * Handy functions for IPv4 socket connections.
5 5
  *
6
- * History:
7
- *      28/01/2014 Creation
8
- *      27/05/2014 New API.
9
- *      28/05/2014 Implement the ipv4_* functions.
10
- *      10/06/2014 Implement the sselect functions using select as backend.
11
- *
12 6
  * Author: Dario Rodriguez dario@softhome.net
13 7
  * This file is licensed under the terms of the GNU LGPL v2+
14 8
  */
... ...
@@ -333,8 +327,10 @@ sselect_getread(sselect *paramssel, int *fds, int sizefds)
333 327
         if(ssel==NULL || fds==NULL || sizefds<1)
334 328
                 return(-1);
335 329
         for(n=0,i=ssel->readresultreturned;i<ssel->maxfd && n<sizefds;i++) {
336
-                if(FD_ISSET(i,&(ssel->readresult)))
330
+                if(FD_ISSET(i,&(ssel->readresult))) {
337 331
                         fds[n++]=i;
332
+                        FD_CLR(i,&(ssel->readresult));
333
+                }
338 334
         }
339 335
         ssel->readresultreturned=i;
340 336
         return(n);
... ...
@@ -348,13 +344,49 @@ sselect_getwrite(sselect *paramssel, int *fds, int sizefds)
348 344
         if(ssel==NULL || fds==NULL || sizefds<1)
349 345
                 return(-1);
350 346
         for(n=0,i=ssel->writeresultreturned;i<ssel->maxfd && n<sizefds;i++) {
351
-                if(FD_ISSET(i,&(ssel->writeresult)))
347
+                if(FD_ISSET(i,&(ssel->writeresult))) {
352 348
                         fds[n++]=i;
349
+                        FD_CLR(i,&(ssel->writeresult));
350
+                }
353 351
         }
354 352
         ssel->writeresultreturned=i;
355 353
         return(n);
356 354
 }
357 355
 
356
+/* advanced sselect functions */
357
+int
358
+sselect_getreadfiltered(sselect *paramssel, fd_set *filter, int *fds, int sizefds)
359
+{
360
+        int i,n;
361
+        _sselect *ssel=(_sselect *)paramssel;
362
+        if(ssel==NULL || fds==NULL || sizefds<1)
363
+                return(-1);
364
+        for(n=0,i=0;i<ssel->maxfd && n<sizefds;i++) {
365
+                if(FD_ISSET(i,&(ssel->readresult)) && FD_ISSET(i,filter)) {
366
+                        fds[n++]=i;
367
+                        FD_CLR(i,&(ssel->readresult));
368
+                }
369
+        }
370
+        return(n);
371
+}
372
+
373
+int
374
+sselect_getwritefiltered(sselect *paramssel, fd_set *filter, int *fds, int sizefds)
375
+{
376
+        int i,n;
377
+        _sselect *ssel=(_sselect *)paramssel;
378
+        if(ssel==NULL || fds==NULL || sizefds<1)
379
+                return(-1);
380
+        for(n=0,i=0;i<ssel->maxfd && n<sizefds;i++) {
381
+                if(FD_ISSET(i,&(ssel->writeresult)) && FD_ISSET(i,filter)) {
382
+                        fds[n++]=i;
383
+                        FD_CLR(i,&(ssel->writeresult));
384
+                }
385
+        }
386
+        return(n);
387
+}
388
+
389
+
358 390
 /* aux functions */
359 391
 void
360 392
 sock_setfast(int fd)
Browse code

socklib: compile fixes

Dario Rodriguez authored on 10/06/2014 10:42:04
Showing 1 changed files
... ...
@@ -29,12 +29,12 @@
29 29
 #include "socklib.h"
30 30
 
31 31
 typedef struct _sselect {
32
-        int fd_set readset;
33
-        int fd_set writeset;
32
+        fd_set readset;
33
+        fd_set writeset;
34 34
         int maxfd;
35 35
         int numfd;
36
-        int fd_set readresult;
37
-        int fd_set writeresult;
36
+        fd_set readresult;
37
+        fd_set writeresult;
38 38
         int sizeresult;
39 39
         int readresultreturned;
40 40
         int writeresultreturned;
... ...
@@ -240,7 +240,6 @@ sselect_init(void)
240 240
 int
241 241
 sselect_reset(sselect *paramssel)
242 242
 {
243
-        int i;
244 243
         _sselect *ssel=(_sselect *)paramssel;
245 244
         if(ssel==NULL)
246 245
                 return(-1);
... ...
@@ -256,9 +255,8 @@ sselect_reset(sselect *paramssel)
256 255
 int
257 256
 sselect_addread(sselect *paramssel, int fd)
258 257
 {
259
-        int i;
260 258
         _sselect *ssel=(_sselect *)paramssel;
261
-        if(ssel==NULL || fd<0 ||  FD_ISSET(fd,&(ssel->readset))
259
+        if(ssel==NULL || fd<0 || FD_ISSET(fd,&(ssel->readset)))
262 260
                 return(-1);
263 261
         FD_SET(fd,&(ssel->readset));
264 262
         if(fd>ssel->maxfd)
... ...
@@ -271,9 +269,8 @@ sselect_addread(sselect *paramssel, int fd)
271 269
 int
272 270
 sselect_addwrite(sselect *paramssel, int fd)
273 271
 {
274
-        int i;
275 272
         _sselect *ssel=(_sselect *)paramssel;
276
-        if(ssel==NULL || fd<0 ||  FD_ISSET(fd,&(ssel->writeset))
273
+        if(ssel==NULL || fd<0 || FD_ISSET(fd,&(ssel->writeset)))
277 274
                 return(-1);
278 275
         FD_SET(fd,&(ssel->writeset));
279 276
         if(fd>ssel->maxfd)
... ...
@@ -285,12 +282,11 @@ sselect_addwrite(sselect *paramssel, int fd)
285 282
 int
286 283
 sselect_delread(sselect *paramssel, int fd)
287 284
 {
288
-        int i;
289 285
         _sselect *ssel=(_sselect *)paramssel;
290
-        if(ssel==NULL || fd<0 || !FD_ISSET(fd,&(ssel->readset))
286
+        if(ssel==NULL || fd<0 || !FD_ISSET(fd,&(ssel->readset)))
291 287
                 return(-1);
292 288
         FD_CLR(fd,&(ssel->readset));
293
-        if(fd>0 && fd==ssel->maxfd && !FD_ISSET(fd,&(ssel->writeset))
289
+        if(fd>0 && fd==ssel->maxfd && !FD_ISSET(fd,&(ssel->writeset)))
294 290
                 ssel->maxfd=fd-1;
295 291
         ssel->numfd--;
296 292
         return(0);
... ...
@@ -300,12 +296,11 @@ sselect_delread(sselect *paramssel, int fd)
300 296
 int
301 297
 sselect_delwrite(sselect *paramssel, int fd)
302 298
 {
303
-        int i;
304 299
         _sselect *ssel=(_sselect *)paramssel;
305
-        if(ssel==NULL || fd<0 || !FD_ISSET(fd,&(ssel->writeset))
300
+        if(ssel==NULL || fd<0 || !FD_ISSET(fd,&(ssel->writeset)))
306 301
                 return(-1);
307 302
         FD_CLR(fd,&(ssel->writeset));
308
-        if(fd>0 && fd==ssel->maxfd && !FD_ISSET(fd,&(ssel->readset))
303
+        if(fd>0 && fd==ssel->maxfd && !FD_ISSET(fd,&(ssel->readset)))
309 304
                 ssel->maxfd=fd-1;
310 305
         ssel->numfd--;
311 306
         return(0);
... ...
@@ -314,8 +309,7 @@ sselect_delwrite(sselect *paramssel, int fd)
314 309
 int
315 310
 sselect_wait(sselect *paramssel, int ms)
316 311
 {
317
-        fd_set readset,writefd;
318
-        timeval tv;
312
+        struct timeval tv;
319 313
         _sselect *ssel=(_sselect *)paramssel;
320 314
         if(ssel==NULL || ms<0)
321 315
                 return(-1);
... ...
@@ -338,7 +332,7 @@ sselect_getread(sselect *paramssel, int *fds, int sizefds)
338 332
         _sselect *ssel=(_sselect *)paramssel;
339 333
         if(ssel==NULL || fds==NULL || sizefds<1)
340 334
                 return(-1);
341
-        for(n=0,i=ssel->readresultreturned;i<ssel->maxfd && n<sizeofds;i++) {
335
+        for(n=0,i=ssel->readresultreturned;i<ssel->maxfd && n<sizefds;i++) {
342 336
                 if(FD_ISSET(i,&(ssel->readresult)))
343 337
                         fds[n++]=i;
344 338
         }
... ...
@@ -353,7 +347,7 @@ sselect_getwrite(sselect *paramssel, int *fds, int sizefds)
353 347
         _sselect *ssel=(_sselect *)paramssel;
354 348
         if(ssel==NULL || fds==NULL || sizefds<1)
355 349
                 return(-1);
356
-        for(n=0,i=ssel->writeresultreturned;i<ssel->maxfd && n<sizeofds;i++) {
350
+        for(n=0,i=ssel->writeresultreturned;i<ssel->maxfd && n<sizefds;i++) {
357 351
                 if(FD_ISSET(i,&(ssel->writeresult)))
358 352
                         fds[n++]=i;
359 353
         }
Browse code

socklib: implement sselect functions using select as backend

Dario Rodriguez authored on 10/06/2014 10:36:24
Showing 1 changed files
... ...
@@ -7,6 +7,7 @@
7 7
  *      28/01/2014 Creation
8 8
  *      27/05/2014 New API.
9 9
  *      28/05/2014 Implement the ipv4_* functions.
10
+ *      10/06/2014 Implement the sselect functions using select as backend.
10 11
  *
11 12
  * Author: Dario Rodriguez dario@softhome.net
12 13
  * This file is licensed under the terms of the GNU LGPL v2+
... ...
@@ -28,12 +29,20 @@
28 29
 #include "socklib.h"
29 30
 
30 31
 typedef struct _sselect {
31
-        int dummy;
32
+        int fd_set readset;
33
+        int fd_set writeset;
34
+        int maxfd;
35
+        int numfd;
36
+        int fd_set readresult;
37
+        int fd_set writeresult;
38
+        int sizeresult;
39
+        int readresultreturned;
40
+        int writeresultreturned;
32 41
 } _sselect;
33 42
 
34 43
 
35 44
 #ifndef FILLTV
36
-#define FILLTV(tv,sec,usec) tv.tv_sec=sec,tv.tv_usec=usec
45
+#define FILLTV(tv,sec,usec) (tv).tv_sec=(sec),(tv).tv_usec=(usec)
37 46
 #endif
38 47
 
39 48
 #ifndef FILLIPV4ADDR
... ...
@@ -217,16 +226,140 @@ sock_setblocking(int fd, int block)
217 226
         return(fcntl(fd,F_SETFL,fl));
218 227
 }
219 228
 
220
-sselect *sselect_init(void);
221
-int sselect_reset(sselect *ssel);
222
-int sselect_addread(sselect *ssel, int fd);
223
-int sselect_addwrite(sselect *ssel, int fd);
224
-int sselect_delread(sselect *ssel, int fd);
225
-int sselect_delwrite(sselect *ssel, int fd);
226
-int sselect_wait(sselect *ssel, int ms);
227
-int sselect_getread(sselect *ssel, int *fds, int sizefds);
228
-int sselect_getwrite(sselect *ssel, int *fds, int sizefds);
229
+sselect *
230
+sselect_init(void)
231
+{
232
+        _sselect *ssel;
233
+        if((ssel=malloc(sizeof(_sselect)))==NULL)
234
+                return(NULL);
235
+        memset(ssel,0,sizeof(_sselect));
236
+        sselect_reset((sselect *)ssel);
237
+        return((sselect *)ssel);
238
+}
239
+
240
+int
241
+sselect_reset(sselect *paramssel)
242
+{
243
+        int i;
244
+        _sselect *ssel=(_sselect *)paramssel;
245
+        if(ssel==NULL)
246
+                return(-1);
247
+        FD_ZERO(&(ssel->readset));
248
+        FD_ZERO(&(ssel->writeset));
249
+        ssel->maxfd=0;
250
+        ssel->numfd=0;
251
+        FD_ZERO(&(ssel->readresult));
252
+        FD_ZERO(&(ssel->writeresult));
253
+        return(0);
254
+}
255
+
256
+int
257
+sselect_addread(sselect *paramssel, int fd)
258
+{
259
+        int i;
260
+        _sselect *ssel=(_sselect *)paramssel;
261
+        if(ssel==NULL || fd<0 ||  FD_ISSET(fd,&(ssel->readset))
262
+                return(-1);
263
+        FD_SET(fd,&(ssel->readset));
264
+        if(fd>ssel->maxfd)
265
+                ssel->maxfd=fd;
266
+        ssel->numfd++;
267
+        return(0);
268
+}
269
+
270
+
271
+int
272
+sselect_addwrite(sselect *paramssel, int fd)
273
+{
274
+        int i;
275
+        _sselect *ssel=(_sselect *)paramssel;
276
+        if(ssel==NULL || fd<0 ||  FD_ISSET(fd,&(ssel->writeset))
277
+                return(-1);
278
+        FD_SET(fd,&(ssel->writeset));
279
+        if(fd>ssel->maxfd)
280
+                ssel->maxfd=fd;
281
+        ssel->numfd++;
282
+        return(0);
283
+}
284
+
285
+int
286
+sselect_delread(sselect *paramssel, int fd)
287
+{
288
+        int i;
289
+        _sselect *ssel=(_sselect *)paramssel;
290
+        if(ssel==NULL || fd<0 || !FD_ISSET(fd,&(ssel->readset))
291
+                return(-1);
292
+        FD_CLR(fd,&(ssel->readset));
293
+        if(fd>0 && fd==ssel->maxfd && !FD_ISSET(fd,&(ssel->writeset))
294
+                ssel->maxfd=fd-1;
295
+        ssel->numfd--;
296
+        return(0);
297
+}
298
+
299
+
300
+int
301
+sselect_delwrite(sselect *paramssel, int fd)
302
+{
303
+        int i;
304
+        _sselect *ssel=(_sselect *)paramssel;
305
+        if(ssel==NULL || fd<0 || !FD_ISSET(fd,&(ssel->writeset))
306
+                return(-1);
307
+        FD_CLR(fd,&(ssel->writeset));
308
+        if(fd>0 && fd==ssel->maxfd && !FD_ISSET(fd,&(ssel->readset))
309
+                ssel->maxfd=fd-1;
310
+        ssel->numfd--;
311
+        return(0);
312
+}
313
+
314
+int
315
+sselect_wait(sselect *paramssel, int ms)
316
+{
317
+        fd_set readset,writefd;
318
+        timeval tv;
319
+        _sselect *ssel=(_sselect *)paramssel;
320
+        if(ssel==NULL || ms<0)
321
+                return(-1);
322
+        memcpy(&(ssel->readresult),&(ssel->readset),sizeof(fd_set));
323
+        memcpy(&(ssel->writeresult),&(ssel->writeset),sizeof(fd_set));
324
+        ssel->readresultreturned=0;
325
+        ssel->writeresultreturned=0;
326
+        FILLTV(tv,(ms/1000),(ms%1000)*1000);
327
+        if((ssel->sizeresult=select(
328
+          ssel->maxfd+1,&(ssel->readresult),
329
+          &(ssel->writeresult),NULL,&tv))<0)
330
+                return(-1);
331
+        return(ssel->sizeresult);
332
+}
229 333
 
334
+int
335
+sselect_getread(sselect *paramssel, int *fds, int sizefds)
336
+{
337
+        int i,n;
338
+        _sselect *ssel=(_sselect *)paramssel;
339
+        if(ssel==NULL || fds==NULL || sizefds<1)
340
+                return(-1);
341
+        for(n=0,i=ssel->readresultreturned;i<ssel->maxfd && n<sizeofds;i++) {
342
+                if(FD_ISSET(i,&(ssel->readresult)))
343
+                        fds[n++]=i;
344
+        }
345
+        ssel->readresultreturned=i;
346
+        return(n);
347
+}
348
+
349
+int
350
+sselect_getwrite(sselect *paramssel, int *fds, int sizefds)
351
+{
352
+        int i,n;
353
+        _sselect *ssel=(_sselect *)paramssel;
354
+        if(ssel==NULL || fds==NULL || sizefds<1)
355
+                return(-1);
356
+        for(n=0,i=ssel->writeresultreturned;i<ssel->maxfd && n<sizeofds;i++) {
357
+                if(FD_ISSET(i,&(ssel->writeresult)))
358
+                        fds[n++]=i;
359
+        }
360
+        ssel->writeresultreturned=i;
361
+        return(n);
362
+}
230 363
 
231 364
 /* aux functions */
232 365
 void
Browse code

Implement the ipv4 part of socklib. Still lacking the sselect functions implementations.

Dario Rodriguez authored on 28/05/2014 12:11:17
Showing 1 changed files
... ...
@@ -6,36 +6,216 @@
6 6
  * History:
7 7
  *      28/01/2014 Creation
8 8
  *      27/05/2014 New API.
9
+ *      28/05/2014 Implement the ipv4_* functions.
9 10
  *
10 11
  * Author: Dario Rodriguez dario@softhome.net
11 12
  * This file is licensed under the terms of the GNU LGPL v2+
12 13
  */
13 14
 
14 15
 #include <stdlib.h>
16
+#include <unistd.h>
15 17
 #include <string.h>
16 18
 #include <netdb.h>
19
+#include <errno.h>
20
+#include <fcntl.h>
17 21
 #include <netinet/in.h>
22
+#include <netinet/tcp.h>
18 23
 #include <sys/types.h>
19 24
 #include <sys/socket.h>
20 25
 #include <sys/select.h>
26
+#include <sys/ioctl.h>
21 27
 
22 28
 #include "socklib.h"
23 29
 
24 30
 typedef struct _sselect {
25
-        int dummy
31
+        int dummy;
26 32
 } _sselect;
27 33
 
28
-char *ipv4_genip(char *hostname, long *resulthostsize);
29
-int ipv4_genport(char *portname, int fallback);
30
-int ipv4_preconnect(char *host, long hostsize, int port); /* setup socket, set non-blocking, connect(2) call */
31
-int ipv4_connect(int fd); /* tests writeability */
32
-int ipv4_postconnect(int fd); /* hopefully connect(2) suceeded, set blocking */
33
-int ipv4_server(int port);
34
-int ipv4_serverbinded(char *host, long hostsize, int port);
35
-int sock_accept(int fd);
36
-int sock_getinfo(int socket, int *iplen, char *ip, int *port); /* ip must be at least 16 bytes to have room for an ipv6 address */
37
-int sock_queued(int socket);
38
-int sock_setblocking(int socket, int block);
34
+
35
+#ifndef FILLTV
36
+#define FILLTV(tv,sec,usec) tv.tv_sec=sec,tv.tv_usec=usec
37
+#endif
38
+
39
+#ifndef FILLIPV4ADDR
40
+#define FILLIPV4ADDR(a,family,addr,port) \
41
+                memset(&(a),0,sizeof(struct sockaddr_in)),\
42
+                s.sin_family=family,\
43
+                s.sin_addr.s_addr=addr,\
44
+                s.sin_port=htons(port)
45
+#endif
46
+
47
+char *
48
+ipv4_genip(char *hostname, long *resulthostsize)
49
+{
50
+        struct addrinfo hints,*ai;
51
+        struct sockaddr_in *in;
52
+        char *host;
53
+        memset(&hints,0,sizeof(hints));
54
+        hints.ai_family=AF_INET;
55
+        if(getaddrinfo(hostname,NULL,&hints,&ai)!=0)
56
+                return(NULL);
57
+        in=(struct sockaddr_in *)ai->ai_addr;
58
+        if(in==NULL || (host=malloc(ai->ai_addrlen))==NULL) {
59
+                freeaddrinfo(ai),ai=NULL;
60
+                return(NULL);
61
+        }
62
+        memcpy(host,ai->ai_addr,ai->ai_addrlen);
63
+        *resulthostsize=ai->ai_addrlen;
64
+        freeaddrinfo(ai),ai=NULL;
65
+        return(host);
66
+}
67
+
68
+int
69
+ipv4_genport(char *portname, int fallback)
70
+{
71
+        struct addrinfo hints,*ai;
72
+        struct sockaddr_in *in;
73
+        char port;
74
+        if(*portname>='0' && *portname<='9')
75
+                return(atoi(portname));
76
+        memset(&hints,0,sizeof(hints));
77
+        hints.ai_family=AF_INET;
78
+        if(getaddrinfo(NULL,portname,&hints,&ai)!=0)
79
+                return(fallback);
80
+        if((in=((struct sockaddr_in *)ai->ai_addr))==NULL) {
81
+                freeaddrinfo(ai),ai=NULL;
82
+                return(fallback);
83
+        }
84
+        port=ntohs(in->sin_port);
85
+        freeaddrinfo(ai),ai=NULL;
86
+        return(port);
87
+}
88
+
89
+int
90
+ipv4_preconnect(char *host, long hostsize, int port) /* setup socket, set non-blocking, connect(2) call */
91
+{
92
+        struct sockaddr_in c,s;
93
+        int fd;
94
+        int res,err;
95
+        FILLIPV4ADDR(c,AF_INET,htonl(INADDR_ANY),0);
96
+        FILLIPV4ADDR(c,AF_INET,htonl(INADDR_ANY),port);
97
+        memcpy(&(s.sin_addr.s_addr),host,hostsize);
98
+        if((fd=socket(AF_INET,SOCK_STREAM,0 /* any protocol */))==-1)
99
+                return(-1);
100
+        if(bind(fd,(struct sockaddr *)&c,sizeof(c))!=0) {
101
+                close(fd),fd=-1;
102
+                return(-1);
103
+        }
104
+        sock_setblocking(fd,0);
105
+        res=connect(fd,(struct sockaddr *)&s,sizeof(s));
106
+        err=errno;
107
+        if(res==-1 && err!=EINPROGRESS) {
108
+                close(fd),fd=-1;
109
+                return(-1);
110
+        }
111
+        return(fd);
112
+}
113
+
114
+int
115
+ipv4_connect(int fd, long timeoutmsec) /* tests writeability */
116
+{
117
+        struct timeval tv;
118
+        fd_set wset;
119
+        FILLTV(tv,timeoutmsec/1000L,(timeoutmsec%(1000L))*1000L);
120
+        FD_ZERO(&wset);
121
+        FD_SET(fd,&wset);
122
+        if(select(fd+1,NULL,&wset,NULL,&tv)>0)
123
+                return(0);
124
+        return(-1);
125
+}
126
+
127
+int
128
+ipv4_postconnect(int fd) /* hopefully connect(2) suceeded, set blocking */
129
+{
130
+        sock_setblocking(fd,1);
131
+        return(0);
132
+}
133
+
134
+int
135
+ipv4_server(int port)
136
+{
137
+        return(ipv4_serverbinded(NULL,0,port));
138
+}
139
+
140
+int
141
+ipv4_serverbinded(char *host, long hostsize, int port)
142
+{
143
+        struct sockaddr_in s;
144
+        int fd;
145
+        if((fd=socket(AF_INET,SOCK_STREAM,0 /* any protocol */))==-1)
146
+                return(-1);
147
+        FILLIPV4ADDR(s,AF_INET,htonl(INADDR_ANY),port);
148
+        if(host!=NULL)
149
+                memcpy(&(s.sin_addr.s_addr),host,hostsize);
150
+        if(bind(fd,(struct sockaddr *)&s,sizeof(s))!=0) {
151
+                close(fd),fd=-1;
152
+                return(-1);
153
+        }
154
+        if(listen(fd,4)==-1) {
155
+                close(fd),fd=-1;
156
+                return(-1);
157
+        }
158
+        return(fd);
159
+}
160
+
161
+int
162
+sock_accept(int fd)
163
+{
164
+        int newfd;
165
+        struct sockaddr_in s;
166
+        socklen_t slen;
167
+        slen=sizeof(s);
168
+        if(fd==-1 || (newfd=accept(fd,(struct sockaddr *)&s,&slen))==-1)
169
+                return(-1);
170
+        return(newfd);
171
+}
172
+
173
+int
174
+sock_getinfo(int fd, int *iplen, char *ip, int *port) /* ip must be at least 16 bytes to have room for an ipv6 address */
175
+{
176
+        struct sockaddr c;
177
+        struct sockaddr_in *c4;
178
+        struct sockaddr_in6 *c6;
179
+        socklen_t clen;
180
+        if(fd==-1)
181
+                return(-1);
182
+        clen=sizeof(c);
183
+        if(getsockname(fd,(struct sockaddr *)&c,&clen)==-1)
184
+                return(-1);
185
+        if(c.sa_family!=AF_INET && c.sa_family!=AF_INET6)
186
+                return(-1);
187
+        if(c.sa_family==AF_INET) {
188
+                c4=(struct sockaddr_in *) &c;
189
+                *iplen=sizeof(c4->sin_addr.s_addr);
190
+                memcpy(ip,&(c4->sin_addr.s_addr),*iplen);
191
+                *port=ntohs(c4->sin_port);
192
+        } else {
193
+                c6=(struct sockaddr_in6 *) &c;
194
+                *iplen=sizeof(c6->sin6_addr);
195
+                memcpy(ip,&(c6->sin6_addr),*iplen);
196
+                *port=ntohs(c6->sin6_port);
197
+        }
198
+        return(0);
199
+}
200
+
201
+int
202
+sock_queued(int fd)
203
+{
204
+        int n;
205
+        if(ioctl(fd,FIONREAD,&n)!=0)
206
+                return(-1);
207
+        return(n);
208
+}
209
+
210
+int
211
+sock_setblocking(int fd, int block)
212
+{
213
+        int fl;
214
+        if((fl=fcntl(fd,F_GETFL,0))==-1)
215
+                return(-1);
216
+        fl=(block)?(fl&(~O_NONBLOCK)):(fl|O_NONBLOCK);
217
+        return(fcntl(fd,F_SETFL,fl));
218
+}
39 219
 
40 220
 sselect *sselect_init(void);
41 221
 int sselect_reset(sselect *ssel);
... ...
@@ -43,7 +223,29 @@ int sselect_addread(sselect *ssel, int fd);
43 223
 int sselect_addwrite(sselect *ssel, int fd);
44 224
 int sselect_delread(sselect *ssel, int fd);
45 225
 int sselect_delwrite(sselect *ssel, int fd);
46
-int sselect_wait(sslect *ssel, int ms);
226
+int sselect_wait(sselect *ssel, int ms);
47 227
 int sselect_getread(sselect *ssel, int *fds, int sizefds);
48 228
 int sselect_getwrite(sselect *ssel, int *fds, int sizefds);
49 229
 
230
+
231
+/* aux functions */
232
+void
233
+sock_setfast(int fd)
234
+{
235
+        int val;
236
+        val=1;
237
+        setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(void *)&val,sizeof(val));
238
+}
239
+
240
+void
241
+sock_setunsafe(int fd)
242
+{
243
+        int val;
244
+        struct linger ltime;
245
+        val=1;
246
+        setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(val));
247
+        ltime.l_onoff=1;
248
+        ltime.l_linger=0;
249
+        setsockopt(fd,SOL_SOCKET,SO_LINGER,(void *)&ltime,sizeof(ltime));
250
+}
251
+
Browse code

API rework to accomodate ipv6 and epoll in the future

Dario Rodriguez authored on 27/05/2014 11:33:45
Showing 1 changed files
... ...
@@ -5,6 +5,7 @@
5 5
  *
6 6
  * History:
7 7
  *      28/01/2014 Creation
8
+ *      27/05/2014 New API.
8 9
  *
9 10
  * Author: Dario Rodriguez dario@softhome.net
10 11
  * This file is licensed under the terms of the GNU LGPL v2+
... ...
@@ -16,54 +17,33 @@
16 17
 #include <netinet/in.h>
17 18
 #include <sys/types.h>
18 19
 #include <sys/socket.h>
20
+#include <sys/select.h>
19 21
 
20 22
 #include "socklib.h"
21 23
 
22
-struct sockaddr *
23
-sock_genip(char *hostname, long *resulthostsize)
24
-{
25
-        struct addrinfo hints,*ai;
26
-        struct sockaddr_in *in;
27
-        char *host;
28
-        memset(&hints,0,sizeof(hints));
29
-        hints.ai_family=AF_UNSPEC;
30
-        if(getaddrinfo(hostname,NULL,&hints,&ai)!=0)
31
-                return(NULL);
32
-        in=(struct sockaddr_in *)ai->addr;
33
-        if((host=malloc(ai->ai_addrlen))==NULL) {
34
-                freeaddrinfo(ai),ai=NULL;
35
-                return(NULL);
36
-        }
24
+typedef struct _sselect {
25
+        int dummy
26
+} _sselect;
37 27
 
38
-        memcpy(host,ai->ai_addr);
39
-        *resulthostsize=ai->ai_addrlen;
40
-        freeaddrinfo(ai),ai=NULL;
41
-        return(host);
42
-}
43
-
44
-int
45
-sock_genport(char *portname, int fallback)
46
-{
47
-        struct addrinfo *ai;
48
-        int port;
49
-        if(getaddrinfo(NULL,portname,NULL,&ai)!=0) {
50
-                return(fallback);
51
-        }
52
-        port=ai->
53
-        *resulthostsize=ai->ai_addrlen;
54
-        freeaddrinfo(ai),ai=NULL;
55
-        return(host);
56
-}
57
-
58
-int
59
-sock_connect(char *host, long hostsize, int port)
60
-{
61
-}
62
-
63
-int sock_server(int port);
64
-int sock_serverbinded(char *host, long hostsize, int port);
65
-int sock_getinfo(int socket, char *ip, int *port);
66
-int sock_select(long timoutms, ...); /* int numfds, int *resfdreadgroup1, int *fdreadgroup1,...,-1,int numfds, int *resfdwritegroup1, int *fdwritegroup1,...,-1); */
28
+char *ipv4_genip(char *hostname, long *resulthostsize);
29
+int ipv4_genport(char *portname, int fallback);
30
+int ipv4_preconnect(char *host, long hostsize, int port); /* setup socket, set non-blocking, connect(2) call */
31
+int ipv4_connect(int fd); /* tests writeability */
32
+int ipv4_postconnect(int fd); /* hopefully connect(2) suceeded, set blocking */
33
+int ipv4_server(int port);
34
+int ipv4_serverbinded(char *host, long hostsize, int port);
35
+int sock_accept(int fd);
36
+int sock_getinfo(int socket, int *iplen, char *ip, int *port); /* ip must be at least 16 bytes to have room for an ipv6 address */
67 37
 int sock_queued(int socket);
68 38
 int sock_setblocking(int socket, int block);
69
-#endif
39
+
40
+sselect *sselect_init(void);
41
+int sselect_reset(sselect *ssel);
42
+int sselect_addread(sselect *ssel, int fd);
43
+int sselect_addwrite(sselect *ssel, int fd);
44
+int sselect_delread(sselect *ssel, int fd);
45
+int sselect_delwrite(sselect *ssel, int fd);
46
+int sselect_wait(sslect *ssel, int ms);
47
+int sselect_getread(sselect *ssel, int *fds, int sizefds);
48
+int sselect_getwrite(sselect *ssel, int *fds, int sizefds);
49
+
Browse code

Added current unfinished sources

Dario Rodriguez authored on 12/03/2014 11:38:34
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,69 @@
1
+/*
2
+ * socklib.c
3
+ *
4
+ * Handy functions for IPv4 socket connections.
5
+ *
6
+ * History:
7
+ *      28/01/2014 Creation
8
+ *
9
+ * Author: Dario Rodriguez dario@softhome.net
10
+ * This file is licensed under the terms of the GNU LGPL v2+
11
+ */
12
+
13
+#include <stdlib.h>
14
+#include <string.h>
15
+#include <netdb.h>
16
+#include <netinet/in.h>
17
+#include <sys/types.h>
18
+#include <sys/socket.h>
19
+
20
+#include "socklib.h"
21
+
22
+struct sockaddr *
23
+sock_genip(char *hostname, long *resulthostsize)
24
+{
25
+        struct addrinfo hints,*ai;
26
+        struct sockaddr_in *in;
27
+        char *host;
28
+        memset(&hints,0,sizeof(hints));
29
+        hints.ai_family=AF_UNSPEC;
30
+        if(getaddrinfo(hostname,NULL,&hints,&ai)!=0)
31
+                return(NULL);
32
+        in=(struct sockaddr_in *)ai->addr;
33
+        if((host=malloc(ai->ai_addrlen))==NULL) {
34
+                freeaddrinfo(ai),ai=NULL;
35
+                return(NULL);
36
+        }
37
+
38
+        memcpy(host,ai->ai_addr);
39
+        *resulthostsize=ai->ai_addrlen;
40
+        freeaddrinfo(ai),ai=NULL;
41
+        return(host);
42
+}
43
+
44
+int
45
+sock_genport(char *portname, int fallback)
46
+{
47
+        struct addrinfo *ai;
48
+        int port;
49
+        if(getaddrinfo(NULL,portname,NULL,&ai)!=0) {
50
+                return(fallback);
51
+        }
52
+        port=ai->
53
+        *resulthostsize=ai->ai_addrlen;
54
+        freeaddrinfo(ai),ai=NULL;
55
+        return(host);
56
+}
57
+
58
+int
59
+sock_connect(char *host, long hostsize, int port)
60
+{
61
+}
62
+
63
+int sock_server(int port);
64
+int sock_serverbinded(char *host, long hostsize, int port);
65
+int sock_getinfo(int socket, char *ip, int *port);
66
+int sock_select(long timoutms, ...); /* int numfds, int *resfdreadgroup1, int *fdreadgroup1,...,-1,int numfds, int *resfdwritegroup1, int *fdwritegroup1,...,-1); */
67
+int sock_queued(int socket);
68
+int sock_setblocking(int socket, int block);
69
+#endif