source: abuse/trunk/src/net/tcpip.h @ 651

Last change on this file since 651 was 555, checked in by Sam Hocevar, 12 years ago

ps3: make everything compile on the PS3. Of course, nothing links yet
because so much support is missing.

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