source: abuse/trunk/src/net/include/tcpip.hpp @ 2

Last change on this file since 2 was 2, checked in by Sam Hocevar, 18 years ago
  • imported original 0.7.0 tarball
File size: 6.7 KB
Line 
1#include "sock.hpp"
2
3#include <stdlib.h>
4#include <fcntl.h>
5#include <sys/ioctl.h>
6#include <sys/stat.h>
7#include <sys/types.h>
8#include <signal.h>
9#include <sys/types.h>
10#include "isllist.hpp"
11
12#ifdef __APPLE__
13typedef int socklen_t;
14#endif
15
16#if (defined(__APPLE__) && !defined(__MACH__))
17#include "GUSI.h"
18#else
19#include <netdb.h>
20#include <netinet/in.h>
21#include <stdio.h>
22#include <string.h>
23#include <sys/time.h>
24#include <sys/ipc.h>
25#include <sys/shm.h>
26#include <sys/socket.h>
27#include <unistd.h>
28#ifdef HAVE_BSTRING_H
29#include <bstring.h>
30#else
31#include <sys/select.h>
32#endif
33#endif
34
35extern fd_set master_set,master_write_set,read_set,exception_set,write_set;
36
37class ip_address : public net_address
38{
39public:
40  sockaddr_in addr;
41
42  virtual protocol protocol_type() const { return net_address::IP; }
43  virtual int equal(const net_address *who) const
44  //{{{
45  {
46    if (who->protocol_type()==IP &&
47        !memcmp(&addr.sin_addr,& ((ip_address *)who)->addr.sin_addr,sizeof(addr.sin_addr)))
48      return 1;
49    else return 0;
50  }
51        //}}}
52  virtual int set_port(int port)  { addr.sin_port=htons(port); return 1; }
53  ip_address(sockaddr_in *Addr) { memcpy(&addr,Addr,sizeof(addr)); }
54  virtual void print()
55  //{{{
56  {
57    unsigned char *c=(unsigned char *) (&addr.sin_addr.s_addr);
58    fprintf(stderr,"%d.%d.%d.%d",c[0],c[1],c[2],c[3]);
59  }
60        //}}}
61  int get_port() { return htons(addr.sin_port); }
62  net_address *copy()  { return new ip_address(&addr); }
63  ip_address() {} ;
64  void store_string(char *st, int st_length)
65  //{{{
66  {
67    char buf[100];
68    unsigned char *c=(unsigned char *) (&addr.sin_addr.s_addr);
69    sprintf(buf,"%d.%d.%d.%d:%d",c[0],c[1],c[2],c[3],htons(addr.sin_port));
70    strncpy(st,buf,st_length);
71    st[st_length-1]=0;   
72  }
73  //}}}
74} ;
75
76class tcpip_protocol : public net_protocol
77{
78protected:
79  // Request Data
80  struct RequestItem
81  {
82        ip_address *addr;
83        char name[256];   //name
84  };
85  typedef isllist<RequestItem *>::iterator p_request;
86  isllist<RequestItem*> servers,returned;
87  net_socket *responder;
88  ip_address *bcast;
89
90  // Notification Data
91  net_socket *notifier;
92  char notify_data[512];
93  int notify_len;
94
95  int handle_notification();
96  int handle_responder();
97public :
98  fd_set master_set,master_write_set,read_set,exception_set,write_set;
99
100  tcpip_protocol();
101  net_address *get_local_address();
102  net_address *get_node_address(char *&server_name, int def_port, int force_port);
103  net_socket *connect_to_server(net_address *addr,
104        net_socket::socket_type sock_type=net_socket::SOCKET_SECURE);
105  net_socket *create_listen_socket(int port, net_socket::socket_type sock_type);
106  int installed() { return 1; }  // always part of unix
107  char *name() { return "UNIX generic TCPIP"; }
108  void cleanup();
109  int select(int block);          // return # of sockets available for read & writing
110 
111  // Notification methods
112  virtual net_socket *start_notify(int port, void *data, int len);
113  virtual void end_notify();
114
115  // Find notifiers methods
116  virtual net_address *find_address(int port, char *name);   // name should be a 256 byte buffer
117  virtual void reset_find_list();
118  virtual ~tcpip_protocol() { cleanup(); }
119} ;
120
121extern tcpip_protocol tcpip;
122
123class unix_fd : public net_socket
124{
125  protected :
126  int fd;
127  public :
128  unix_fd(int fd) : fd(fd) { };
129  virtual int error()                             { return FD_ISSET(fd,&tcpip.exception_set); }
130  virtual int ready_to_read()                     { return FD_ISSET(fd,&tcpip.read_set); }
131  virtual int ready_to_write()                   
132  {
133    struct timeval tv={0,0};     // don't wait
134    fd_set write_check; 
135    FD_ZERO(&write_check); 
136    FD_SET(fd,&write_check);     
137    select(FD_SETSIZE,NULL,&write_check,NULL,&tv);
138    return FD_ISSET(fd,&write_check);
139  }
140  virtual int write(void *buf, int size, net_address *addr=NULL);
141  virtual int read(void *buf, int size, net_address **addr);
142
143  virtual ~unix_fd()                            { read_unselectable();  write_unselectable(); close(fd); }
144  virtual void read_selectable()                   { FD_SET(fd,&tcpip.master_set); }
145  virtual void read_unselectable()                 { FD_CLR(fd,&tcpip.master_set); }
146  virtual void write_selectable()                  { FD_SET(fd,&tcpip.master_write_set); }
147  virtual void write_unselectable()                { FD_CLR(fd,&tcpip.master_write_set); }
148  int get_fd() { return fd; }
149 
150  void broadcastable();
151} ;
152
153class tcp_socket : public unix_fd
154{
155  int listening;
156  public :
157  tcp_socket(int fd) : unix_fd(fd) { listening=0; };
158  virtual int listen(int port)
159  {
160    sockaddr_in host;
161    memset( (char*) &host,0, sizeof(host));
162    host.sin_family = AF_INET;
163    host.sin_port = htons(port);
164    host.sin_addr.s_addr = htonl(INADDR_ANY);
165    if (bind(fd, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
166    {
167      fprintf(stderr,"net driver : could not bind socket to port %d\n",port);
168      return 0;
169    }
170    if (::listen(fd,5)==-1)
171    {
172      fprintf(stderr,"net driver : could not listen to socket on port %d\n",port);   
173      return 0;
174    }
175    listening=1;
176    return 1;
177  }
178  virtual net_socket *accept(net_address *&addr)
179  {
180    if (listening)
181    {
182      struct sockaddr_in from;
183      socklen_t addr_len=sizeof(from);
184      int new_fd=::accept(fd,(sockaddr *)&from,&addr_len);
185      if (new_fd>=0)
186      {
187        addr=new ip_address(&from);
188        return new tcp_socket(new_fd);
189      }
190      else
191      { addr=NULL; return 0; }
192    }
193    return 0;
194  }
195} ;
196
197class udp_socket : public unix_fd
198{
199  public :
200  udp_socket(int fd) : unix_fd(fd) { };
201  virtual int read(void *buf, int size, net_address **addr)
202  {
203    int tr;
204    if (addr)
205    {
206      *addr=new ip_address;
207      socklen_t addr_size=sizeof(sockaddr_in);
208      tr=recvfrom(fd,buf,size,0, (sockaddr *) &((ip_address *)(*addr))->addr,&addr_size);
209    } else
210      tr=recv(fd,buf,size,0);
211    return tr;
212  }
213  virtual int write(void *buf, int size, net_address *addr=NULL)
214  {
215    if (addr)
216      return sendto(fd,buf,size,0,(sockaddr *)(&((ip_address *)addr)->addr),sizeof(((ip_address *)addr)->addr));
217    else
218      return ::write(fd,(char*)buf,size);     
219  }
220  virtual int listen(int port)
221  {
222    sockaddr_in host;
223    memset( (char*) &host,0, sizeof(host));
224    host.sin_family = AF_INET;
225    host.sin_port = htons(port);
226    host.sin_addr.s_addr = htonl(INADDR_ANY);
227    if (bind(fd, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
228    {
229      fprintf(stderr,"net driver : could not bind socket to port %d\n",port);
230      return 0;
231    }
232    return 1;
233  }
234
235} ;
236
Note: See TracBrowser for help on using the repository browser.