FACT++  1.0
tcpip.c
Go to the documentation of this file.
1 /*
2  * DNA (Delphi Network Access) implements the network layer for the DIM
3  * (Delphi Information Managment) System.
4  *
5  * Started : 10-11-91
6  * Last modification : 29-07-94
7  * Written by : C. Gaspar
8  * Adjusted by : G.C. Ballintijn
9  *
10  */
11 
12 /*
13 #define DEBUG
14 */
15 
16 #ifdef WIN32
17 #define FD_SETSIZE 16384
18 #define poll(pfd,nfds,timeout) WSAPoll(pfd,nfds,timeout)
19 #define ioctl ioctlsocket
20 
21 #define closesock myclosesocket
22 #define readsock recv
23 #define writesock send
24 
25 #define EINTR WSAEINTR
26 #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
27 #define EWOULDBLOCK WSAEWOULDBLOCK
28 #define ECONNREFUSED WSAECONNREFUSED
29 #define HOST_NOT_FOUND WSAHOST_NOT_FOUND
30 #define NO_DATA WSANO_DATA
31 
32 #else
33 /*
34 #define closesock(s) shutdown(s,2)
35 */
36 #define closesock(s) close(s)
37 #define readsock(a,b,c,d) read(a,b,c)
38 
39 #if defined(__linux__) && !defined (darwin)
40 #define writesock(a,b,c,d) send(a,b,c,MSG_NOSIGNAL)
41 #else
42 #define writesock(a,b,c,d) write(a,b,c)
43 #endif
44 
45 #ifdef solaris
46 #define BSD_COMP
47 /*
48 #include <thread.h>
49 */
50 #endif
51 
52 #ifdef LYNXOS
53 #ifdef RAID
54 typedef int pid_t;
55 #endif
56 #endif
57 
58 #include <ctype.h>
59 #include <sys/socket.h>
60 #include <fcntl.h>
61 #include <netinet/in.h>
62 #include <netinet/tcp.h>
63 #include <signal.h>
64 #include <sys/ioctl.h>
65 #include <errno.h>
66 #include <netdb.h>
67 
68 #endif
69 
70 #ifdef __linux__
71 #include <poll.h>
72 #define MY_FD_ZERO(set)
73 #define MY_FD_SET(fd, set) poll_add(fd)
74 #define MY_FD_CLR(fd, set)
75 #define MY_FD_ISSET(fd, set) poll_test(fd)
76 #else
77 #define MY_FD_ZERO(set) FD_ZERO(set)
78 #define MY_FD_SET(fd, set) FD_SET(fd, set)
79 #define MY_FD_CLR(fd, set) FD_CLR(fd, set)
80 #define MY_FD_ISSET(fd, set) FD_ISSET(fd, set)
81 #endif
82 
83 #include <stdio.h>
84 #include <time.h>
85 #define DIMLIB
86 #include <dim.h>
87 
88 #define ushort unsigned short
89 
90 static int Threads_on = 0;
91 
92 static int init_done = FALSE; /* Is this module initialized? */
93 static int queue_id = 0;
94 
95 #ifdef WIN32
96 static struct sockaddr_in DIM_sockname;
97 #endif
98 
99 static int DIM_IO_path[2] = {-1,-1};
100 static int DIM_IO_Done = 0;
101 static int DIM_IO_valid = 1;
102 
103 static int Listen_backlog = SOMAXCONN;
104 static int Keepalive_timeout_set = 0;
106 static int Write_timeout_set = 0;
109 
112 
114 {
116 }
117 
119 {
120  return(Listen_backlog);
121 }
122 
124 {
125  Keepalive_timeout_set = secs;
126 }
127 
129 {
130  int ret;
131  extern int get_keepalive_tmout();
132 
133  if(!(ret = Keepalive_timeout_set))
134  {
135  ret = get_keepalive_tmout();
136  Keepalive_timeout_set = ret;
137  }
138  return(ret);
139 }
140 
141 void dim_set_write_timeout(int secs)
142 {
143  Write_timeout = secs;
144  Write_timeout_set = 1;
145 }
146 
148 {
149  int ret;
150  extern int get_write_tmout();
151 
152  if(!Write_timeout_set)
153  {
154  if((ret = get_write_tmout()))
155  Write_timeout = ret;
156  }
157  return(Write_timeout);
158 }
159 
161 {
162  if(size >= TCP_SND_BUF_SIZE)
163  {
165  Tcpip_max_io_data_write = size - 16;
166  return(1);
167  }
168  return(0);
169 }
170 
172 {
173  return(Write_buffer_size);
174 }
175 
177 {
178  if(size >= TCP_RCV_BUF_SIZE)
179  {
181  Tcpip_max_io_data_read = size - 16;
182  return(1);
183  }
184  return(0);
185 }
186 
188 {
189  return(Read_buffer_size);
190 }
191 
192 #ifdef WIN32
193 int init_sock()
194 {
195  WORD wVersionRequested;
196  WSADATA wsaData;
197  int err;
198  static int sock_init_done = 0;
199 
200  if(sock_init_done) return(1);
201  wVersionRequested = MAKEWORD( 2, 0 );
202  err = WSAStartup( wVersionRequested, &wsaData );
203 
204  if ( err != 0 )
205  {
206  return(0);
207  }
208 
209  /* Confirm that the WinSock DLL supports 2.0.*/
210  /* Note that if the DLL supports versions greater */
211  /* than 2.0 in addition to 2.0, it will still return */
212  /* 2.0 in wVersion since that is the version we */
213  /* requested. */
214 
215  if ( LOBYTE( wsaData.wVersion ) != 2 ||
216  HIBYTE( wsaData.wVersion ) != 0 )
217  {
218  WSACleanup( );
219  return(0);
220  }
221  sock_init_done = 1;
222  return(1);
223 }
224 
225 int myclosesocket(int path)
226 {
227  int code, ret;
228  code = WSAGetLastError();
229  ret = closesocket(path);
230  WSASetLastError(code);
231  return ret;
232 }
233 #endif
234 
235 int dim_tcpip_init(int thr_flag)
236 {
237 #ifdef WIN32
238  int addr, flags = 1;
239 /*
240  void tcpip_task();
241 */
242  void create_io_thread(void);
243 #else
244  struct sigaction sig_info;
245  sigset_t set;
246  void io_sig_handler();
247  void dummy_io_sig_handler();
248  void tcpip_pipe_sig_handler();
249 #endif
250  extern int get_write_tmout();
251 
252  if(init_done)
253  return(1);
254 
256 #ifdef WIN32
257  init_sock();
258  Threads_on = 1;
259 #else
260  if(thr_flag)
261  {
262  Threads_on = 1;
263  }
264  else
265  {
266  sigemptyset(&set);
267 
268  sigaddset(&set,SIGALRM);
269  sig_info.sa_handler = io_sig_handler;
270  sig_info.sa_mask = set;
271 #ifndef LYNXOS
272  sig_info.sa_flags = SA_RESTART;
273 #else
274  sig_info.sa_flags = 0;
275 #endif
276 
277  if( sigaction(SIGIO, &sig_info, 0) < 0 )
278  {
279  perror( "sigaction(SIGIO)" );
280  exit(1);
281  }
282 
283  sigemptyset(&set);
284  sig_info.sa_handler = tcpip_pipe_sig_handler;
285  sig_info.sa_mask = set;
286 #ifndef LYNXOS
287  sig_info.sa_flags = SA_RESTART;
288 #else
289  sig_info.sa_flags = 0;
290 #endif
291 
292  if( sigaction(SIGPIPE, &sig_info, 0) < 0 ) {
293  perror( "sigaction(SIGPIPE)" );
294  exit(1);
295  }
296 
297  }
298 #endif
299  if(Threads_on)
300  {
301 #ifdef WIN32
302  if(DIM_IO_path[0] == -1)
303  {
304  if( (DIM_IO_path[0] = (int)socket(AF_INET, SOCK_STREAM, 0)) == -1 )
305  {
306  perror("socket");
307  return(0);
308  }
309 
310  DIM_sockname.sin_family = PF_INET;
311  addr = 0;
312  DIM_sockname.sin_addr = *((struct in_addr *) &addr);
313  DIM_sockname.sin_port = htons((ushort) 2000);
314  ioctl(DIM_IO_path[0], FIONBIO, &flags);
315  }
316 #else
317  if(DIM_IO_path[0] == -1)
318  {
319  pipe(DIM_IO_path);
320  }
321 #endif
322  }
323  if(!queue_id)
324  queue_id = dtq_create();
325 
326 #ifdef WIN32
327 /*
328 #ifndef STDCALL
329  tid = _beginthread((void *)(void *)tcpip_task,0,NULL);
330 #else
331  tid = _beginthreadex(NULL, NULL,
332  tcpip_task,0,0,NULL);
333 #endif
334 */
335  create_io_thread();
336 #endif
337  init_done = 1;
338  return(1);
339 }
340 
342 {
343 #ifdef WIN32
345 #else
346  close(DIM_IO_path[0]);
347  close(DIM_IO_path[1]);
348 #endif
349  DIM_IO_path[0] = -1;
350  DIM_IO_path[1] = -1;
351  DIM_IO_Done = 0;
352  init_done = 0;
353 }
354 
355 static int enable_sig(int conn_id)
356 {
357  int ret = 1, flags = 1;
358 #ifndef WIN32
359  int pid;
360 #endif
361 
362 #ifdef DEBUG
363  if(!Net_conns[conn_id].channel)
364  {
365  printf("Enabling signals on channel 0\n");
366  fflush(stdout);
367  }
368 #endif
369 
370  if(!init_done)
371  {
372  dim_tcpip_init(0);
373  }
374  if(Threads_on)
375  {
376 #ifdef WIN32
377  DIM_IO_valid = 0;
378 /*
379  ret = connect(DIM_IO_path[0], (struct sockaddr*)&DIM_sockname, sizeof(DIM_sockname));
380 */
382  DIM_IO_path[0] = -1;
383  if( (DIM_IO_path[0] = (int)socket(AF_INET, SOCK_STREAM, 0)) == -1 )
384  {
385  perror("socket");
386  return(1);
387  }
388  ret = ioctl(DIM_IO_path[0], FIONBIO, &flags);
389  if(ret != 0)
390  {
391  perror("ioctlsocket");
392  }
393  DIM_IO_valid = 1;
394 #else
395  if(DIM_IO_path[1] != -1)
396  {
397  if(!DIM_IO_Done)
398  {
399  DIM_IO_Done = 1;
400  write(DIM_IO_path[1], &flags, 4);
401  }
402  }
403 #endif
404  }
405 #ifndef WIN32
406  if(!Threads_on)
407  {
408  pid = getpid();
409 
410 #ifndef __linux__
411  ret = ioctl(Net_conns[conn_id].channel, SIOCSPGRP, &pid );
412 #else
413  ret = fcntl(Net_conns[conn_id].channel,F_SETOWN, pid);
414 #endif
415  if(ret == -1)
416  {
417 #ifdef DEBUG
418  printf("ioctl returned -1\n");
419 #endif
420  return(ret);
421  }
422  }
423  ret = ioctl(Net_conns[conn_id].channel, FIOASYNC, &flags );
424  if(ret == -1)
425  {
426 #ifdef DEBUG
427  printf("ioctl1 returned -1\n");
428 #endif
429  return(ret);
430  }
431 
432  flags = fcntl(Net_conns[conn_id].channel,F_GETFD,0);
433 #ifdef DEBUG
434  if(flags == -1)
435  {
436  printf("error\n");
437  }
438 #endif
439  ret = fcntl(Net_conns[conn_id].channel,F_SETFD, flags | FD_CLOEXEC );
440  if(ret == -1)
441  {
442 #ifdef DEBUG
443  printf("ioctl2 returned -1\n");
444 #endif
445  return(ret);
446  }
447 #endif
448  return(1);
449 }
450 
451 #ifdef __linux__
452 int tcpip_get_send_space(int conn_id)
453 {
454  int ret, n_bytes;
455 
456  ret = ioctl(Net_conns[conn_id].channel, TIOCOUTQ, &n_bytes );
457  if(ret == -1)
458  {
459 #ifdef DEBUG
460  printf("Couln't get send buffer free size, ret = %d\n", ret);
461 #endif
462  return(0);
463  }
464 /*
465  printf("tcpip_get_send_space %d\n", Write_buffer_size - n_bytes);
466 */
467  return(Write_buffer_size - n_bytes);
468 }
469 #endif
470 
471 /*
472 static void dump_list()
473 {
474  int i;
475 
476  for( i = 1; i < Curr_N_Conns; i++ )
477  if( Dna_conns[i].busy ) {
478  printf( "dump_list: conn_id=%d reading=%d\n",
479  i, Net_conns[i].reading );
480  }
481 }
482 */
483 
484 #ifdef __linux__
485 static struct pollfd *Pollfds = 0;
486 static int Pollfd_size = 0;
487 
488 static int poll_create()
489 {
490  int i;
491  if(Pollfd_size == 0)
492  {
493  Pollfd_size = Curr_N_Conns;
494  Pollfds = malloc(Pollfd_size * sizeof(struct pollfd));
495  Pollfds[0].fd = -1;
496  for(i = 0; i < Pollfd_size; i++)
497  {
498  Pollfds[i].events = POLLIN;
499  }
500  }
501  else if(Pollfd_size < Curr_N_Conns)
502  {
503  free(Pollfds);
504  Pollfd_size = Curr_N_Conns;
505  Pollfds = malloc(Pollfd_size * sizeof(struct pollfd));
506  Pollfds[0].fd = -1;
507  for(i = 0; i < Pollfd_size; i++)
508  {
509  Pollfds[i].events = POLLIN;
510  }
511  }
512  return 1;
513 }
514 
515 static int poll_add(int fd)
516 {
517  Pollfds[0].fd = fd;
518  return 1;
519 }
520 
521 static int poll_test(int fd)
522 {
523  if(Pollfds[0].fd == fd)
524  {
525  if( (Pollfds[0].revents & POLLIN) || (Pollfds[0].revents & POLLHUP) )
526  {
527  Pollfds[0].revents = 0;
528  return 1;
529  }
530  }
531  return 0;
532 }
533 #endif
534 
535 static int list_to_fds( fd_set *fds )
536 {
537  int i;
538  int found = 0;
539 
540  DISABLE_AST
541 #ifdef __linux__
542  if(fds) {}
543  poll_create();
544 #else
545  FD_ZERO( fds ) ;
546 #endif
547  for( i = 1; i < Curr_N_Conns; i++ )
548  {
549 #ifdef __linux__
550  Pollfds[i].fd = -1;
551 #endif
552  if( Dna_conns[i].busy )
553  {
554  if(Net_conns[i].channel)
555  {
556  found = 1;
557 #ifdef __linux__
558  Pollfds[i].fd = Net_conns[i].channel;
559 #else
560  FD_SET( Net_conns[i].channel, fds );
561 #endif
562 
563  }
564  }
565  }
566  ENABLE_AST
567  return(found);
568 }
569 
570 static int fds_get_entry( fd_set *fds, int *conn_id )
571 {
572  int i;
573 
574 #ifdef __linux__
575  int index = *conn_id;
576  if(fds) {}
577  index++;
578  for( i = index; i < Pollfd_size; i++ )
579  {
580  if( Dna_conns[i].busy && (
581  (Pollfds[i].revents & POLLIN) || (Pollfds[i].revents & POLLHUP) ) )
582  {
583  Pollfds[i].revents = 0;
584  if(Net_conns[i].channel)
585  {
586  *conn_id = i;
587  return 1;
588  }
589  }
590  }
591  return 0;
592 #else
593  for( i = 1; i < Curr_N_Conns; i++ )
594  {
595  if( Dna_conns[i].busy &&
596  FD_ISSET(Net_conns[i].channel, fds) )
597  {
598  if(Net_conns[i].channel)
599  {
600  *conn_id = i;
601  return 1;
602  }
603  }
604  }
605  return 0;
606 #endif
607 }
608 
609 #if defined(__linux__) && !defined (darwin)
610 
611 void tcpip_set_keepalive( int channel, int tmout )
612 {
613  int val;
614 
615  /* Enable keepalive for the given channel */
616  val = 1;
617  setsockopt(channel, SOL_SOCKET, SO_KEEPALIVE, (char*)&val, sizeof(val));
618 
619  /* Set the keepalive poll interval to something small.
620  Warning: this section may not be portable! */
621  val = tmout;
622  setsockopt(channel, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&val, sizeof(val));
623  val = 3;
624  setsockopt(channel, IPPROTO_TCP, TCP_KEEPCNT, (char*)&val, sizeof(val));
625  val = tmout/3;
626  setsockopt(channel, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&val, sizeof(val));
627 }
628 
629 #else
630 
631 static void tcpip_test_write( int conn_id )
632 {
633  /* Write to every socket we use, which uses the TCPIP protocol,
634  * which has an established connection (reading), which is currently
635  * not writing data, so we can check if it is still alive.
636  */
637  time_t cur_time;
638 
639  if(strcmp(Net_conns[conn_id].node,"MYNODE"))
640  {
641  cur_time = time(NULL);
642  if( cur_time - Net_conns[conn_id].last_used > Net_conns[conn_id].timeout )
643  {
644  dna_test_write( conn_id );
645  }
646  }
647 }
648 
649 #endif
650 
651 void tcpip_set_test_write(int conn_id, int timeout)
652 {
653 
654 #if defined(__linux__) && !defined (darwin)
655  tcpip_set_keepalive(Net_conns[conn_id].channel, timeout);
656 #else
657 
658  Net_conns[conn_id].timr_ent = dtq_add_entry( queue_id, timeout,
659  tcpip_test_write, conn_id );
660  Net_conns[conn_id].timeout = timeout;
661  Net_conns[conn_id].last_used = time(NULL);
662 
663 #endif
664 
665 }
666 
667 void tcpip_rem_test_write(int conn_id)
668 {
669  if(Net_conns[conn_id].timr_ent)
670  {
671  dtq_rem_entry(queue_id, Net_conns[conn_id].timr_ent);
672  Net_conns[conn_id].timr_ent = NULL;
673  }
674  Net_conns[conn_id].last_used = time(NULL);
675 }
676 
677 void tcpip_pipe_sig_handler( int num )
678 {
679  if(num){}
680 /*
681  printf( "*** pipe_sig_handler called ***\n" );
682 */
683 }
684 
685 static int get_bytes_to_read(int conn_id)
686 {
687  int i, ret, count = 0;
688 
689  for(i = 0; i < 3; i++)
690  {
691  ret = ioctl( Net_conns[conn_id].channel, FIONREAD, &count );
692  if( ret != 0)
693  {
694  count = 0;
695  break;
696  }
697  if(count > 0)
698  {
699  break;
700  }
701  }
702  return(count);
703 }
704 
705 static int do_read( int conn_id )
706 {
707  /* There is 'data' pending, read it.
708  */
709  int len, totlen, size, count;
710  char *p;
711 
712  count = get_bytes_to_read(conn_id);
713  if(!count)
714  {
715 /*
716  dna_report_error(conn_id, -1,
717  "Connection closed by remote peer", DIM_ERROR, DIMTCPRDERR);
718  printf("conn_id %d\n", conn_id);
719 */
720  Net_conns[conn_id].read_rout( conn_id, -1, 0 );
721  return 0;
722  }
723 
724  size = Net_conns[conn_id].size;
725  p = Net_conns[conn_id].buffer;
726  totlen = 0;
727 /*
728  count = 1;
729 */
730  while( size > 0 && count > 0 )
731  {
732 /*
733  would this be better? not sure afterwards...
734  nbytes = (size < count) ? size : count;
735  if( (len = readsock(Net_conns[conn_id].channel, p, (size_t)nbytes, 0)) <= 0 )
736 */
737  if( (len = (int)readsock(Net_conns[conn_id].channel, p, (size_t)size, 0)) <= 0 )
738  { /* Connection closed by other side. */
739  Net_conns[conn_id].read_rout( conn_id, -1, 0 );
740  return 0;
741  }
742  else
743  {
744 
745  /*
746  printf("tcpip: read %d bytes:\n",len);
747  printf( "buffer[0]=%d\n", vtohl((int *)p[0]));
748  printf( "buffer[1]=%d\n", vtohl((int *)p[1]));
749  printf( "buffer[2]=%x\n", vtohl((int *)p[2]));
750  */
751  totlen += len;
752  size -= len;
753  p += len;
754  }
755  if(size)
756  count = get_bytes_to_read(conn_id);
757  }
758 
759  Net_conns[conn_id].last_used = time(NULL);
760  Net_conns[conn_id].read_rout( conn_id, 1, totlen );
761  return 1;
762 }
763 
764 
765 void do_accept( int conn_id )
766 {
767  /* There is a 'connect' pending, serve it.
768  */
769  struct sockaddr_in other;
770  int othersize;
771 
772  othersize = sizeof(other);
773  memset( (char *) &other, 0, (size_t)othersize );
774  Net_conns[conn_id].mbx_channel = (int)accept( Net_conns[conn_id].channel,
775  (struct sockaddr*)&other, (unsigned int *)&othersize );
776  if( Net_conns[conn_id].mbx_channel < 0 )
777  {
778  return;
779  }
780 /*
781  else
782  {
783  int all, a, b, c, d;
784  char *pall;
785 
786  all = other.sin_addr.s_addr;
787  pall = &all;
788  a = pall[0];
789  a &= 0x000000ff;
790  b = pall[1];
791  b &= 0x000000ff;
792  c = pall[2];
793  c &= 0x000000ff;
794  d = pall[3];
795  d &= 0x000000ff;
796 printf("TCPIP got %d.%d.%d.%d \n",
797  a,b,c,d);
798  if((a == 134) && (b == 79) && (c == 157) && (d == 40))
799  {
800  closesock(Net_conns[conn_id].mbx_channel);
801  return;
802  }
803  }
804 */
805 
806  Net_conns[conn_id].last_used = time(NULL);
807  Net_conns[conn_id].read_rout( Net_conns[conn_id].mbx_channel,
808  conn_id, TCPIP );
809 }
810 
811 void io_sig_handler(int num)
812 {
813  fd_set rfds;
814  int conn_id, ret, selret, count;
815  struct timeval timeout;
816 
817  if(num){}
818  do
819  {
820  timeout.tv_sec = 0; /* Don't wait, just poll */
821  timeout.tv_usec = 0;
822  list_to_fds( &rfds );
823 #ifdef __linux__
824  selret = poll(Pollfds, Pollfd_size, 0);
825 #else
826  selret = select(FD_SETSIZE, &rfds, NULL, NULL, &timeout);
827 #endif
828  if(selret > 0)
829  {
830  conn_id = 0;
831  while( (ret = fds_get_entry( &rfds, &conn_id )) > 0 )
832  {
833  if( Net_conns[conn_id].reading )
834  {
835  count = 0;
836  do
837  {
838  if(Net_conns[conn_id].channel)
839  {
840  do_read( conn_id );
841  count = get_bytes_to_read(conn_id);
842  }
843  else
844  {
845  count = 0;
846  }
847  }while(count > 0 );
848  }
849  else
850  {
851  do_accept( conn_id );
852  }
853  MY_FD_CLR( (unsigned)Net_conns[conn_id].channel, &rfds );
854  }
855  }
856  }while(selret > 0);
857 }
858 
859 void tcpip_task( void *dummy)
860 {
861  /* wait for an IO signal, find out what is happening and
862  * call the right routine to handle the situation.
863  */
864  fd_set rfds, *pfds;
865 #ifndef __linux__
866  fd_set efds;
867 #endif
868  int conn_id, ret, count;
869 #ifndef WIN32
870  int data;
871 #endif
872  if(dummy){}
873  while(1)
874  {
875  while(!DIM_IO_valid)
876  dim_usleep(1000);
877 
878  list_to_fds( &rfds );
879  MY_FD_ZERO(&efds);
880 #ifdef WIN32
881  pfds = &efds;
882 #else
883  pfds = &rfds;
884 #endif
885  MY_FD_SET( DIM_IO_path[0], pfds );
886 #ifdef __linux__
887  ret = poll(Pollfds, Pollfd_size, -1);
888 #else
889  ret = select(FD_SETSIZE, &rfds, NULL, &efds, NULL);
890 #endif
891  if(ret <= 0)
892  {
893  printf("poll returned %d, errno %d\n", ret, errno);
894  }
895  if(ret > 0)
896  {
897  if(MY_FD_ISSET(DIM_IO_path[0], pfds) )
898  {
899 #ifndef WIN32
900  read(DIM_IO_path[0], &data, 4);
901  DIM_IO_Done = 0;
902 #endif
903  MY_FD_CLR( (unsigned)DIM_IO_path[0], pfds );
904  }
905 /*
906  {
907  DISABLE_AST
908 */
909  conn_id = 0;
910  while( (ret = fds_get_entry( &rfds, &conn_id )) > 0 )
911  {
912  if( Net_conns[conn_id].reading )
913  {
914  count = 0;
915  do
916  {
917  DISABLE_AST
918  if(Net_conns[conn_id].channel)
919  {
920  do_read( conn_id );
921  count = get_bytes_to_read(conn_id);
922  }
923  else
924  {
925  count = 0;
926  }
927  ENABLE_AST
928  }while(count > 0 );
929  }
930  else
931  {
932  DISABLE_AST
933  do_accept( conn_id );
934  ENABLE_AST
935  }
936  MY_FD_CLR( (unsigned)Net_conns[conn_id].channel, &rfds );
937  }
938 /*
939  ENABLE_AST
940  }
941 */
942 #ifndef WIN32
943  return;
944 #endif
945  }
946  }
947 }
948 
949 int tcpip_start_read( int conn_id, char *buffer, int size, void (*ast_routine)() )
950 {
951  /* Install signal handler stuff on the socket, and record
952  * some necessary information: we are reading, and want size
953  * as size, and use buffer.
954  */
955 
956  Net_conns[conn_id].read_rout = ast_routine;
957  Net_conns[conn_id].buffer = buffer;
958  Net_conns[conn_id].size = size;
959  if(Net_conns[conn_id].reading == -1)
960  {
961  if(enable_sig( conn_id ) == -1)
962  {
963 #ifdef DEBUG
964  printf("START_READ - enable_sig returned -1\n");
965 #endif
966  return(0);
967  }
968  }
969  Net_conns[conn_id].reading = TRUE;
970  return(1);
971 }
972 
973 int check_node_addr( char *node, unsigned char *ipaddr)
974 {
975 unsigned char *ptr;
976 int ret;
977 
978  ptr = (unsigned char *)node+(int)strlen(node)+1;
979  ipaddr[0] = *ptr++;
980  ipaddr[1] = *ptr++;
981  ipaddr[2] = *ptr++;
982  ipaddr[3] = *ptr++;
983  if( (ipaddr[0] == 0xff) &&
984  (ipaddr[1] == 0xff) &&
985  (ipaddr[2] == 0xff) &&
986  (ipaddr[3] == 0xff) )
987  {
988  errno = ECONNREFUSED; /* fake an error code */
989 #ifdef WIN32
990  WSASetLastError(errno);
991 #endif
992  return(0);
993  }
994  if( gethostbyaddr(ipaddr, sizeof(ipaddr), AF_INET) == (struct hostent *)0 )
995  {
996 #ifndef WIN32
997  ret = h_errno;
998 #else
999  ret = WSAGetLastError();
1000 #endif
1001  if((ret == HOST_NOT_FOUND) || (ret == NO_DATA))
1002  return(0);
1003 /*
1004  errno = ECONNREFUSED;
1005 #ifdef WIN32
1006  WSASetLastError(errno);
1007 #endif
1008  return(0);
1009 */
1010  }
1011  return(1);
1012 }
1013 
1014 int tcpip_open_client( int conn_id, char *node, char *task, int port )
1015 {
1016  /* Create connection: create and initialize socket stuff. Try
1017  * and make a connection with the server.
1018  */
1019  struct sockaddr_in sockname;
1020 #ifndef VxWorks
1021  struct hostent *host = 0;
1022 #else
1023  int host_addr;
1024 #endif
1025  int path, val, ret_code, ret;
1026  int a,b,c,d;
1027 /* Fix for gcc 4.6 "dereferencing type-punned pointer will break strict-aliasing rules"?!*/
1028  unsigned char ipaddr_buff[4];
1029  unsigned char *ipaddr = ipaddr_buff;
1030  int host_number = 0;
1031 
1032  dim_tcpip_init(0);
1033  if(isdigit(node[0]))
1034  {
1035  sscanf(node,"%d.%d.%d.%d",&a, &b, &c, &d);
1036  ipaddr[0] = (unsigned char)a;
1037  ipaddr[1] = (unsigned char)b;
1038  ipaddr[2] = (unsigned char)c;
1039  ipaddr[3] = (unsigned char)d;
1040  host_number = 1;
1041 /*
1042 #ifndef VxWorks
1043  if( gethostbyaddr(ipaddr, sizeof(ipaddr), AF_INET) == (struct hostent *)0 )
1044  {
1045 #ifndef WIN32
1046  ret = h_errno;
1047 #else
1048  ret = WSAGetLastError();
1049 #endif
1050 // if((ret == HOST_NOT_FOUND) || (ret == NO_DATA))
1051 // {
1052 // if(!check_node_addr(node, ipaddr))
1053 // return(0);
1054 // }
1055  }
1056 #endif
1057 */
1058  }
1059 #ifndef VxWorks
1060  else if( (host = gethostbyname(node)) == (struct hostent *)0 )
1061  {
1062  if(!check_node_addr(node, ipaddr))
1063  return(0);
1064  host_number = 1;
1065 /*
1066  ptr = (unsigned char *)node+(int)strlen(node)+1;
1067  ipaddr[0] = *ptr++;
1068  ipaddr[1] = *ptr++;
1069  ipaddr[2] = *ptr++;
1070  ipaddr[3] = *ptr++;
1071  host_number = 1;
1072  if( (ipaddr[0] == 0xff) &&
1073  (ipaddr[1] == 0xff) &&
1074  (ipaddr[2] == 0xff) &&
1075  (ipaddr[3] == 0xff) )
1076  {
1077  errno = ECONNREFUSED;
1078 #ifdef WIN32
1079  WSASetLastError(errno);
1080 #endif
1081  return(0);
1082  }
1083  if( gethostbyaddr(ipaddr, sizeof(ipaddr), AF_INET) == (struct hostent *)0 )
1084  {
1085  errno = ECONNREFUSED;
1086 #ifdef WIN32
1087  WSASetLastError(errno);
1088 #endif
1089  return(0);
1090  }
1091 */
1092  }
1093 #else
1094  *(strchr(node,'.')) = '\0';
1095  host_addr = hostGetByName(node);
1096  printf("node %s addr: %x\n",node, host_addr);
1097 #endif
1098 
1099  if( (path = (int)socket(AF_INET, SOCK_STREAM, 0)) == -1 )
1100  {
1101  perror("socket");
1102  return(0);
1103  }
1104 
1105  val = 1;
1106 
1107  if ((ret_code = setsockopt(path, IPPROTO_TCP, TCP_NODELAY,
1108  (char*)&val, sizeof(val))) == -1 )
1109  {
1110 #ifdef DEBUG
1111  printf("Couln't set TCP_NODELAY\n");
1112 #endif
1113  closesock(path);
1114  return(0);
1115  }
1116 
1117  val = Write_buffer_size;
1118  if ((ret_code = setsockopt(path, SOL_SOCKET, SO_SNDBUF,
1119  (char*)&val, sizeof(val))) == -1 )
1120  {
1121 #ifdef DEBUG
1122  printf("Couln't set SO_SNDBUF\n");
1123 #endif
1124  closesock(path);
1125  return(0);
1126  }
1127 
1128  val = Read_buffer_size;
1129  if ((ret_code = setsockopt(path, SOL_SOCKET, SO_RCVBUF,
1130  (char*)&val, sizeof(val))) == -1 )
1131  {
1132 #ifdef DEBUG
1133  printf("Couln't set SO_RCVBUF\n");
1134 #endif
1135  closesock(path);
1136  return(0);
1137  }
1138 
1139 #if defined(__linux__) && !defined (darwin)
1140  val = 2;
1141  if ((ret_code = setsockopt(path, IPPROTO_TCP, TCP_SYNCNT,
1142  (char*)&val, sizeof(val))) == -1 )
1143  {
1144 #ifdef DEBUG
1145  printf("Couln't set TCP_SYNCNT\n");
1146 #endif
1147  }
1148 #endif
1149 
1150  sockname.sin_family = PF_INET;
1151 #ifndef VxWorks
1152  if(host_number)
1153  sockname.sin_addr = *((struct in_addr *) ipaddr);
1154  else
1155  sockname.sin_addr = *((struct in_addr *) host->h_addr);
1156 #else
1157  if(host_number)
1158  sockname.sin_addr = *((struct in_addr *) ipaddr);
1159  else
1160  sockname.sin_addr = *((struct in_addr *) &host_addr);
1161 #endif
1162  sockname.sin_port = htons((ushort) port); /* port number to send to */
1163  while((ret = connect(path, (struct sockaddr*)&sockname, sizeof(sockname))) == -1 )
1164  {
1165  if(errno != EINTR)
1166  {
1167  closesock(path);
1168  return(0);
1169  }
1170  }
1171  strcpy( Net_conns[conn_id].node, node );
1172  strcpy( Net_conns[conn_id].task, task );
1173  Net_conns[conn_id].channel = path;
1174  Net_conns[conn_id].port = port;
1175  Net_conns[conn_id].last_used = time(NULL);
1176  Net_conns[conn_id].reading = -1;
1177  Net_conns[conn_id].timr_ent = NULL;
1178  Net_conns[conn_id].write_timedout = 0;
1179  return(1);
1180 }
1181 
1182 int tcpip_open_server( int conn_id, char *task, int *port )
1183 {
1184  /* Create connection: create and initialize socket stuff,
1185  * find a free port on this node.
1186  */
1187  struct sockaddr_in sockname;
1188  int path, val, ret_code, ret;
1189 
1190  dim_tcpip_init(0);
1191  if( (path = (int)socket(AF_INET, SOCK_STREAM, 0)) == -1 )
1192  {
1193  return(0);
1194  }
1195 
1196  val = 1;
1197  if ((ret_code = setsockopt(path, IPPROTO_TCP, TCP_NODELAY,
1198  (char*)&val, sizeof(val))) == -1 )
1199 
1200  {
1201 #ifdef DEBUG
1202  printf("Couln't set TCP_NODELAY\n");
1203 #endif
1204  closesock(path);
1205  return(0);
1206  }
1207 
1208  val = Write_buffer_size;
1209  if ((ret_code = setsockopt(path, SOL_SOCKET, SO_SNDBUF,
1210  (void *)&val, sizeof(val))) == -1 )
1211  {
1212 #ifdef DEBUG
1213  printf("Couln't set SO_SNDBUF\n");
1214 #endif
1215  closesock(path);
1216  return(0);
1217  }
1218 /*
1219  sval1 = sizeof(val1);
1220  if ((ret_code = getsockopt(path, SOL_SOCKET, SO_SNDBUF,
1221  (void *)&val1, &sval1)) == -1 )
1222  {
1223 #ifdef DEBUG
1224  printf("Couln't set SO_SNDBUF\n");
1225 #endif
1226  closesock(path);
1227  return(0);
1228  }
1229 printf("Set size to %d, got size %d\n", val, val1);
1230 */
1231  val = Read_buffer_size;
1232  if ((ret_code = setsockopt(path, SOL_SOCKET, SO_RCVBUF,
1233  (void *)&val, sizeof(val))) == -1 )
1234  {
1235 #ifdef DEBUG
1236  printf("Couln't set SO_RCVBUF\n");
1237 #endif
1238  closesock(path);
1239  return(0);
1240  }
1241 
1242  if( *port == SEEK_PORT )
1243  { /* Search a free one. */
1244  *port = START_PORT_RANGE - 1;
1245  do
1246  {
1247  (*port)++;
1248  sockname.sin_family = AF_INET;
1249  sockname.sin_addr.s_addr = INADDR_ANY;
1250  sockname.sin_port = htons((ushort) *port);
1251  if( *port > STOP_PORT_RANGE ) {
1252  errno = EADDRNOTAVAIL; /* fake an error code */
1253  closesock(path);
1254 #ifdef WIN32
1255  WSASetLastError(errno);
1256 #endif
1257  return(0);
1258  }
1259  ret = bind(path, (struct sockaddr*)&sockname, sizeof(sockname));
1260 /*
1261 printf("Trying port %d, ret = %d\n", *port, ret);
1262 */
1263  } while( ret == -1 );
1264 /*
1265  } while( bind(path, (struct sockaddr*)&sockname, sizeof(sockname)) == -1 );
1266 */
1267  } else {
1268 #ifndef WIN32
1269  val = 1;
1270  if( setsockopt(path, SOL_SOCKET, SO_REUSEADDR, (char*)&val,
1271  sizeof(val)) == -1 )
1272  {
1273 #ifdef DEBUG
1274  printf("Couln't set SO_REUSEADDR\n");
1275 #endif
1276  closesock(path);
1277  return(0);
1278  }
1279 #endif
1280  sockname.sin_family = AF_INET;
1281  sockname.sin_addr.s_addr = INADDR_ANY;
1282  sockname.sin_port = htons((ushort) *port);
1283  if( (ret = bind(path, (struct sockaddr*) &sockname, sizeof(sockname))) == -1 )
1284  {
1285  closesock(path);
1286  return(0);
1287  }
1288  }
1289 
1290  if( (ret = listen(path, Listen_backlog)) == -1 )
1291  {
1292  closesock(path);
1293  return(0);
1294  }
1295 
1296  strcpy( Net_conns[conn_id].node, "MYNODE" );
1297  strcpy( Net_conns[conn_id].task, task );
1298  Net_conns[conn_id].channel = path;
1299  Net_conns[conn_id].port = *port;
1300  Net_conns[conn_id].last_used = time(NULL);
1301  Net_conns[conn_id].reading = -1;
1302  Net_conns[conn_id].timr_ent = NULL;
1303  Net_conns[conn_id].write_timedout = 0;
1304  return(1);
1305 }
1306 
1307 
1308 int tcpip_start_listen( int conn_id, void (*ast_routine)() )
1309 {
1310  /* Install signal handler stuff on the socket, and record
1311  * some necessary information: we are NOT reading, thus
1312  * no size.
1313  */
1314 
1315  Net_conns[conn_id].read_rout = ast_routine;
1316  Net_conns[conn_id].size = -1;
1317  if(Net_conns[conn_id].reading == -1)
1318  {
1319  if(enable_sig( conn_id ) == -1)
1320  {
1321 #ifdef DEBUG
1322  printf("START_LISTEN - enable_sig returned -1\n");
1323 #endif
1324  return(0);
1325  }
1326  }
1327  Net_conns[conn_id].reading = FALSE;
1328  return(1);
1329 }
1330 
1331 
1332 int tcpip_open_connection( int conn_id, int path )
1333 {
1334  /* Fill in/clear some fields, the node and task field
1335  * get filled in later by a special packet.
1336  */
1337  int val, ret_code;
1338 
1339 
1340  val = 1;
1341  if ((ret_code = setsockopt(path, IPPROTO_TCP, TCP_NODELAY,
1342  (char*)&val, sizeof(val))) == -1 )
1343  {
1344 #ifdef DEBUG
1345  printf("Couln't set TCP_NODELAY\n");
1346 #endif
1347  closesock(path);
1348  return(0);
1349  }
1350  val = Write_buffer_size;
1351  if ((ret_code = setsockopt(path, SOL_SOCKET, SO_SNDBUF,
1352  (char*)&val, sizeof(val))) == -1 )
1353  {
1354 #ifdef DEBUG
1355  printf("Couln't set SO_SNDBUF\n");
1356 #endif
1357  closesock(path);
1358  return(0);
1359  }
1360 
1361  val = Read_buffer_size;
1362  if ((ret_code = setsockopt(path, SOL_SOCKET, SO_RCVBUF,
1363  (char*)&val, sizeof(val))) == -1 )
1364  {
1365 #ifdef DEBUG
1366  printf("Couln't set SO_RCVBUF\n");
1367 #endif
1368  closesock(path);
1369  return(0);
1370  }
1371 
1372  Net_conns[conn_id].channel = path;
1373  Net_conns[conn_id].node[0] = 0;
1374  Net_conns[conn_id].task[0] = 0;
1375  Net_conns[conn_id].port = 0;
1376  Net_conns[conn_id].reading = -1;
1377  Net_conns[conn_id].timr_ent = NULL;
1378  Net_conns[conn_id].write_timedout = 0;
1379  return(1);
1380 }
1381 
1382 
1383 void tcpip_get_node_task( int conn_id, char *node, char *task )
1384 {
1385  strcpy( node, Net_conns[conn_id].node );
1386  strcpy( task, Net_conns[conn_id].task );
1387 }
1388 
1389 int tcpip_write( int conn_id, char *buffer, int size )
1390 {
1391  /* Do a (synchronous) write to conn_id.
1392  */
1393  int wrote;
1394 
1395  wrote = (int)writesock( Net_conns[conn_id].channel, buffer, (size_t)size, 0 );
1396  if( wrote == -1 ) {
1397 /*
1398  Net_conns[conn_id].read_rout( conn_id, -1, 0 );
1399 */
1400  dna_report_error(conn_id, 0,
1401  "Writing (blocking) to", DIM_ERROR, DIMTCPWRRTY);
1402  return(0);
1403  }
1404  return(wrote);
1405 }
1406 
1407 int set_non_blocking(int channel)
1408 {
1409  int ret, flags = 1;
1410  ret = ioctl(channel, FIONBIO, &flags );
1411  if(ret == -1)
1412  {
1413 #ifdef DEBUG
1414  printf("ioctl non block returned -1\n");
1415 #endif
1416  return(ret);
1417  }
1418  return(1);
1419 }
1420 
1421 int set_blocking(int channel)
1422 {
1423  int ret, flags = 0;
1424  ret = ioctl(channel, FIONBIO, &flags );
1425  if(ret == -1)
1426  {
1427 #ifdef DEBUG
1428  printf("ioctl block returned -1\n");
1429 #endif
1430  return(ret);
1431  }
1432  return(1);
1433 }
1434 
1435 int tcpip_write_nowait( int conn_id, char *buffer, int size )
1436 {
1437  /* Do a (asynchronous) write to conn_id.
1438  */
1439  int wrote, ret, selret;
1440  int tcpip_would_block();
1441 #ifdef __linux__
1442  struct pollfd pollitem;
1443 #else
1444  struct timeval timeout;
1445  fd_set wfds;
1446 #endif
1447 
1448  set_non_blocking(Net_conns[conn_id].channel);
1449 /*
1450 #ifdef __linux__
1451  tcpip_get_send_space(conn_id);
1452 #endif
1453 */
1454  wrote = (int)writesock( Net_conns[conn_id].channel, buffer, (size_t)size, 0 );
1455 #ifndef WIN32
1456  ret = errno;
1457 #else
1458  ret = WSAGetLastError();
1459 #endif
1460 /*
1461  if((wrote == -1) && (!tcpip_would_block(ret)))
1462  {
1463  dna_report_error(conn_id, 0,
1464  "Writing (non-blocking) to", DIM_ERROR, DIMTCPWRRTY);
1465 printf("Writing %d, ret = %d\n", size, ret);
1466  }
1467 */
1468  set_blocking(Net_conns[conn_id].channel);
1469  if(wrote == -1)
1470  {
1471  if(tcpip_would_block(ret))
1472  {
1473 #ifdef __linux__
1474  pollitem.fd = Net_conns[conn_id].channel;
1475  pollitem.events = POLLOUT;
1476  pollitem.revents = 0;
1477  selret = poll(&pollitem, 1, Write_timeout*1000);
1478 #else
1479  timeout.tv_sec = Write_timeout;
1480  timeout.tv_usec = 0;
1481  FD_ZERO(&wfds);
1482  FD_SET( Net_conns[conn_id].channel, &wfds);
1483  selret = select(FD_SETSIZE, NULL, &wfds, NULL, &timeout);
1484 #endif
1485  if(selret > 0)
1486  {
1487  wrote = (int)writesock( Net_conns[conn_id].channel, buffer, (size_t)size, 0 );
1488  if( wrote == -1 )
1489  {
1490  dna_report_error(conn_id, 0,
1491  "Writing to", DIM_ERROR, DIMTCPWRRTY);
1492  return(0);
1493  }
1494  }
1495  }
1496  else
1497  {
1498  dna_report_error(conn_id, 0,
1499  "Writing (non-blocking) to", DIM_ERROR, DIMTCPWRRTY);
1500  return(0);
1501  }
1502  }
1503  if(wrote == -1)
1504  {
1505  Net_conns[conn_id].write_timedout = 1;
1506  }
1507  return(wrote);
1508 }
1509 
1510 int tcpip_close( int conn_id )
1511 {
1512  int channel;
1513  /* Clear all traces of the connection conn_id.
1514  */
1515  if(Net_conns[conn_id].timr_ent)
1516  {
1517  dtq_rem_entry(queue_id, Net_conns[conn_id].timr_ent);
1518  Net_conns[conn_id].timr_ent = NULL;
1519  }
1520  channel = Net_conns[conn_id].channel;
1521  Net_conns[conn_id].channel = 0;
1522  Net_conns[conn_id].port = 0;
1523  Net_conns[conn_id].node[0] = 0;
1524  Net_conns[conn_id].task[0] = 0;
1525  if(channel)
1526  {
1527  if(Net_conns[conn_id].write_timedout)
1528  {
1529  Net_conns[conn_id].write_timedout = 0;
1530 #if defined(__linux__) && !defined (darwin)
1531  shutdown(channel, 2);
1532 #endif
1533  }
1534  closesock(channel);
1535  }
1536  return(1);
1537 }
1538 
1539 
1540 int tcpip_failure( int code )
1541 {
1542  return(!code);
1543 }
1544 
1545 int tcpip_would_block( int code )
1546 {
1547  if(code == EWOULDBLOCK)
1548  return(1);
1549  return(0);
1550 }
1551 
1552 void tcpip_report_error( int code )
1553 {
1554 #ifndef WIN32
1555  if(code){}
1556  perror("tcpip");
1557 #else
1558  int my_perror();
1559 
1560  my_perror("tcpip", code);
1561 #endif
1562 }
1563 
1564 #ifdef WIN32
1565 int my_perror(char *str, int error)
1566 {
1567 int code;
1568 
1569  if(error <= 0)
1570  code = WSAGetLastError();
1571  else
1572  code = error;
1573  printf("new - %s\n",strerror(code));
1574  printf("%s: ",str);
1575  switch(code)
1576  {
1577  case WSAEWOULDBLOCK:
1578  printf("Operation would block");
1579  break;
1580  case WSAEINPROGRESS:
1581  printf("Operation now in progress");
1582  break;
1583  case WSAEALREADY:
1584  printf("Operation already in progress");
1585  break;
1586  case WSAENOTSOCK:
1587  printf("Socket operation on non-socket");
1588  break;
1589  case WSAEDESTADDRREQ:
1590  printf("Destination address required");
1591  break;
1592  case WSAEMSGSIZE:
1593  printf("Message too long");
1594  break;
1595  case WSAEPROTOTYPE:
1596  printf("Protocol wrong type for socket");
1597  break;
1598  case WSAENOPROTOOPT:
1599  printf("Protocol not available");
1600  break;
1601  case WSAEPROTONOSUPPORT:
1602  printf("Protocol not supported");
1603  break;
1604  case WSAESOCKTNOSUPPORT:
1605  printf("Socket type not supported");
1606  break;
1607  case WSAEOPNOTSUPP:
1608  printf("Operation not supported on transport endpoint");
1609  break;
1610  case WSAEPFNOSUPPORT:
1611  printf("Protocol family not supported");
1612  break;
1613  case WSAEAFNOSUPPORT:
1614  printf("Address family not supported by protocol");
1615  break;
1616  case WSAEADDRINUSE:
1617  printf("Address already in use");
1618  break;
1619  case WSAEADDRNOTAVAIL:
1620  printf("Cannot assign requested address");
1621  break;
1622  case WSAENETDOWN:
1623  printf("Network is down");
1624  break;
1625  case WSAENETUNREACH:
1626  printf("Network is unreachable");
1627  break;
1628  case WSAENETRESET:
1629  printf("Network dropped connection because of reset");
1630  break;
1631  case WSAECONNABORTED:
1632  printf("Software caused connection abort");
1633  break;
1634  case WSAECONNRESET:
1635  printf("Connection reset by peer");
1636  break;
1637  case WSAENOBUFS:
1638  printf("No buffer space available");
1639  break;
1640  case WSAEISCONN:
1641  printf("Transport endpoint is already connected");
1642  break;
1643  case WSAENOTCONN:
1644  printf("Transport endpoint is not connected");
1645  break;
1646  case WSAESHUTDOWN:
1647  printf("Cannot send after transport endpoint shutdown");
1648  break;
1649  case WSAETOOMANYREFS:
1650  printf("Too many references: cannot splice");
1651  break;
1652  case WSAETIMEDOUT:
1653  printf("Connection timed out");
1654  break;
1655  case WSAECONNREFUSED:
1656  printf("Connection refused");
1657  break;
1658  case WSAELOOP:
1659  printf("Too many symbolic links encountered");
1660  break;
1661  case WSAENAMETOOLONG:
1662  printf("File name too long");
1663  break;
1664  case WSAEHOSTDOWN:
1665  printf("Host is down");
1666  break;
1667  case WSAEHOSTUNREACH:
1668  printf("No route to host");
1669  break;
1670  case WSAENOTEMPTY:
1671  printf("Directory not empty");
1672  break;
1673  case WSAEUSERS:
1674  printf("Too many users");
1675  break;
1676  case WSAEDQUOT:
1677  printf("Quota exceeded");
1678  break;
1679  case WSAESTALE:
1680  printf("Stale NFS file handle");
1681  break;
1682  case WSAEREMOTE:
1683  printf("Object is remote");
1684  break;
1685  case WSAHOST_NOT_FOUND:
1686  printf("Host not found");
1687  break;
1688  case WSATRY_AGAIN:
1689  printf("Host not found, or SERVERFAIL");
1690  break;
1691  case WSANO_RECOVERY:
1692  printf("Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1693  break;
1694  case WSANO_DATA:
1695  printf("Valid name, no data record of requested type");
1696  break;
1697  default:
1698  printf("Unknown error %d",code);
1699  }
1700  printf("\n");
1701  return(1);
1702 }
1703 
1704 void my_strerror(int error, char *msg)
1705 {
1706 int code;
1707 char str[128];
1708 
1709  if(error <= 0)
1710  code = WSAGetLastError();
1711  else
1712  code = error;
1713  switch(code)
1714  {
1715  case WSAEWOULDBLOCK:
1716  sprintf(str,"Operation would block");
1717  break;
1718  case WSAEINPROGRESS:
1719  sprintf(str,"Operation now in progress");
1720  break;
1721  case WSAEALREADY:
1722  sprintf(str,"Operation already in progress");
1723  break;
1724  case WSAENOTSOCK:
1725  sprintf(str,"Socket operation on non-socket");
1726  break;
1727  case WSAEDESTADDRREQ:
1728  sprintf(str,"Destination address required");
1729  break;
1730  case WSAEMSGSIZE:
1731  sprintf(str,"Message too long");
1732  break;
1733  case WSAEPROTOTYPE:
1734  sprintf(str,"Protocol wrong type for socket");
1735  break;
1736  case WSAENOPROTOOPT:
1737  sprintf(str,"Protocol not available");
1738  break;
1739  case WSAEPROTONOSUPPORT:
1740  sprintf(str,"Protocol not supported");
1741  break;
1742  case WSAESOCKTNOSUPPORT:
1743  sprintf(str,"Socket type not supported");
1744  break;
1745  case WSAEOPNOTSUPP:
1746  sprintf(str,"Operation not supported on transport endpoint");
1747  break;
1748  case WSAEPFNOSUPPORT:
1749  sprintf(str,"Protocol family not supported");
1750  break;
1751  case WSAEAFNOSUPPORT:
1752  sprintf(str,"Address family not supported by protocol");
1753  break;
1754  case WSAEADDRINUSE:
1755  sprintf(str,"Address already in use");
1756  break;
1757  case WSAEADDRNOTAVAIL:
1758  sprintf(str,"Cannot assign requested address");
1759  break;
1760  case WSAENETDOWN:
1761  sprintf(str,"Network is down");
1762  break;
1763  case WSAENETUNREACH:
1764  sprintf(str,"Network is unreachable");
1765  break;
1766  case WSAENETRESET:
1767  sprintf(str,"Network dropped connection because of reset");
1768  break;
1769  case WSAECONNABORTED:
1770  sprintf(str,"Software caused connection abort");
1771  break;
1772  case WSAECONNRESET:
1773  sprintf(str,"Connection reset by peer");
1774  break;
1775  case WSAENOBUFS:
1776  sprintf(str,"No buffer space available");
1777  break;
1778  case WSAEISCONN:
1779  sprintf(str,"Transport endpoint is already connected");
1780  break;
1781  case WSAENOTCONN:
1782  sprintf(str,"Transport endpoint is not connected");
1783  break;
1784  case WSAESHUTDOWN:
1785  sprintf(str,"Cannot send after transport endpoint shutdown");
1786  break;
1787  case WSAETOOMANYREFS:
1788  sprintf(str,"Too many references: cannot splice");
1789  break;
1790  case WSAETIMEDOUT:
1791  sprintf(str,"Connection timed out");
1792  break;
1793  case WSAECONNREFUSED:
1794  sprintf(str,"Connection refused");
1795  break;
1796  case WSAELOOP:
1797  sprintf(str,"Too many symbolic links encountered");
1798  break;
1799  case WSAENAMETOOLONG:
1800  sprintf(str,"File name too long");
1801  break;
1802  case WSAEHOSTDOWN:
1803  sprintf(str,"Host is down");
1804  break;
1805  case WSAEHOSTUNREACH:
1806  sprintf(str,"No route to host");
1807  break;
1808  case WSAENOTEMPTY:
1809  sprintf(str,"Directory not empty");
1810  break;
1811  case WSAEUSERS:
1812  sprintf(str,"Too many users");
1813  break;
1814  case WSAEDQUOT:
1815  sprintf(str,"Quota exceeded");
1816  break;
1817  case WSAESTALE:
1818  sprintf(str,"Stale NFS file handle");
1819  break;
1820  case WSAEREMOTE:
1821  sprintf(str,"Object is remote");
1822  break;
1823  case WSAHOST_NOT_FOUND:
1824  sprintf(str,"Host not found");
1825  break;
1826  case WSATRY_AGAIN:
1827  sprintf(str,"Host not found, or SERVERFAIL");
1828  break;
1829  case WSANO_RECOVERY:
1830  sprintf(str,"Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1831  break;
1832  case WSANO_DATA:
1833  sprintf(str,"Valid name, no data record of requested type");
1834  break;
1835  default:
1836  sprintf(str,"Unknown error %d",code);
1837  }
1838  strcpy(msg, str);
1839 }
1840 #endif
1841 
1842 void tcpip_get_error( char *str, int code )
1843 {
1844  DISABLE_AST
1845 #ifndef WIN32
1846  if(code){}
1847  if((errno == 0) && (h_errno == HOST_NOT_FOUND))
1848  strcpy(str,"Host not found");
1849  else
1850  strcpy(str, strerror(errno));
1851 #else
1852  my_strerror(code, str);
1853 #endif
1854  ENABLE_AST
1855 }
Definition: dns.c:26
int dim_get_keepalive_timeout()
Definition: tcpip.c:128
int tcpip_start_listen(int conn_id, void(*ast_routine)())
Definition: tcpip.c:1308
void dna_test_write(int conn_id)
Definition: dna.c:335
void(* read_rout)()
Definition: dim.h:400
DllExp DIM_NOSHARE int Curr_N_Conns
Definition: conn_handler.c:33
#define DIMTCPWRRTY
Definition: dim_common.h:294
static void tcpip_test_write(int conn_id)
Definition: tcpip.c:631
void io_sig_handler(int num)
Definition: tcpip.c:811
static int DIM_IO_valid
Definition: tcpip.c:101
TIMR_ENT * timr_ent
Definition: dim.h:413
void dim_tcpip_stop()
Definition: tcpip.c:341
char * buffer
Definition: dim.h:401
char task[MAX_TASK_NAME]
Definition: dim.h:408
int dim_get_listen_backlog()
Definition: tcpip.c:118
#define TCP_SND_BUF_SIZE
Definition: dim.h:166
int i
Definition: db_dim_client.c:21
DllExp DIM_NOSHARE NET_CONNECTION * Net_conns
Definition: conn_handler.c:32
#define TCPIP
Definition: dim.h:194
#define TRUE
Definition: dim.h:135
#define ushort
Definition: tcpip.c:88
char str[80]
Definition: test_client.c:7
int dim_get_read_buffer_size()
Definition: tcpip.c:187
int size
Definition: dim.h:402
void dim_usleep(int usecs)
Definition: dtq.c:293
void tcpip_get_error(char *str, int code)
Definition: tcpip.c:1842
#define FALSE
Definition: dim.h:136
int get_write_tmout()
Definition: utilities.c:298
int dtq_create()
Definition: dtq.c:353
static int get_bytes_to_read(int conn_id)
Definition: tcpip.c:685
#define MY_FD_SET(fd, set)
Definition: tcpip.c:78
void * malloc()
Definition: EventBuilder.cc:99
static int DIM_IO_Done
Definition: tcpip.c:100
static int DIM_IO_path[2]
Definition: tcpip.c:99
char node[MAX_NODE_NAME]
Definition: dim.h:407
#define MY_FD_ISSET(fd, set)
Definition: tcpip.c:80
#define MY_FD_ZERO(set)
Definition: tcpip.c:77
#define TCP_RCV_BUF_SIZE
Definition: dim.h:165
int mbx_channel
Definition: dim.h:399
int dim_tcpip_init(int thr_flag)
Definition: tcpip.c:235
int tcpip_would_block(int code)
Definition: tcpip.c:1545
int Tcpip_max_io_data_write
Definition: tcpip.c:110
void dim_set_listen_backlog(int size)
Definition: tcpip.c:113
int channel
Definition: dim.h:398
int tcpip_write_nowait(int conn_id, char *buffer, int size)
Definition: tcpip.c:1435
int port
Definition: dim.h:409
static int Threads_on
Definition: tcpip.c:90
time_t last_used
Definition: dim.h:414
void tcpip_rem_test_write(int conn_id)
Definition: tcpip.c:667
int set_blocking(int channel)
Definition: tcpip.c:1421
int dtq_rem_entry(int queue_id, TIMR_ENT *entry)
Definition: dtq.c:503
static int do_read(int conn_id)
Definition: tcpip.c:705
int tcpip_start_read(int conn_id, char *buffer, int size, void(*ast_routine)())
Definition: tcpip.c:949
#define writesock(a, b, c, d)
Definition: tcpip.c:42
#define readsock(a, b, c, d)
Definition: tcpip.c:37
static int init_done
Definition: tcpip.c:92
void dim_set_write_timeout(int secs)
Definition: tcpip.c:141
int tcpip_close(int conn_id)
Definition: tcpip.c:1510
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
Definition: smartfact.txt:92
void dna_report_error(int conn_id, int code, char *routine_name, int severity, int errcode)
Definition: dna.c:903
#define START_PORT_RANGE
Definition: dim.h:201
static int fds_get_entry(fd_set *fds, int *conn_id)
Definition: tcpip.c:570
#define closesock(s)
Definition: tcpip.c:36
int buffer[BUFFSIZE]
Definition: db_dim_client.c:14
int count
Definition: db_dim_server.c:18
void dim_set_keepalive_timeout(int secs)
Definition: tcpip.c:123
int size
Definition: db_dim_server.c:17
int Tcpip_max_io_data_read
Definition: tcpip.c:111
int tcpip_write(int conn_id, char *buffer, int size)
Definition: tcpip.c:1389
float data[4 *1440]
#define MY_FD_CLR(fd, set)
Definition: tcpip.c:79
void free(void *mem)
TIMR_ENT * dtq_add_entry(int queue_id, int time, void(*user_routine)(), dim_long tag)
Definition: dtq.c:399
DllExp DIM_NOSHARE DNA_CONNECTION * Dna_conns
Definition: conn_handler.c:31
static int Keepalive_timeout_set
Definition: tcpip.c:104
int tcpip_open_client(int conn_id, char *node, char *task, int port)
Definition: tcpip.c:1014
int dim_set_write_buffer_size(int size)
Definition: tcpip.c:160
static int enable_sig(int conn_id)
Definition: tcpip.c:355
void tcpip_get_node_task(int conn_id, char *node, char *task)
Definition: tcpip.c:1383
static int Write_buffer_size
Definition: tcpip.c:107
#define WRITE_TMOUT
Definition: dim.h:206
static int Write_timeout
Definition: tcpip.c:105
static int queue_id
Definition: tcpip.c:93
int timeout
Definition: dim.h:411
static int Read_buffer_size
Definition: tcpip.c:108
void tcpip_task(void *dummy)
Definition: tcpip.c:859
int dim_get_write_timeout()
Definition: tcpip.c:147
#define SEEK_PORT
Definition: dim.h:140
int tcpip_open_server(int conn_id, char *task, int *port)
Definition: tcpip.c:1182
static int Listen_backlog
Definition: tcpip.c:103
void tcpip_pipe_sig_handler(int num)
Definition: tcpip.c:677
int check_node_addr(char *node, unsigned char *ipaddr)
Definition: tcpip.c:973
int write_timedout
Definition: dim.h:412
#define STOP_PORT_RANGE
Definition: dim.h:202
int dim_get_write_buffer_size()
Definition: tcpip.c:171
int get_keepalive_tmout()
Definition: utilities.c:287
int tcpip_failure(int code)
Definition: tcpip.c:1540
sprintf(name1,"NewService%d", i)
static int Write_timeout_set
Definition: tcpip.c:106
int reading
Definition: dim.h:410
void do_accept(int conn_id)
Definition: tcpip.c:765
static int list_to_fds(fd_set *fds)
Definition: tcpip.c:535
void tcpip_set_test_write(int conn_id, int timeout)
Definition: tcpip.c:651
int tcpip_open_connection(int conn_id, int path)
Definition: tcpip.c:1332
int dim_set_read_buffer_size(int size)
Definition: tcpip.c:176
void tcpip_report_error(int code)
Definition: tcpip.c:1552
int set_non_blocking(int channel)
Definition: tcpip.c:1407