WvStreams
wvudp.cc
1/*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * WvUDPStream can send and receive packets on a connectionless UDP socket.
6 * See wvudp.h for details.
7 */
8#include "wvudp.h"
9
10#ifndef WIN32
11#include <sys/socket.h>
12#else
13#define setsockopt(a,b,c,d,e) setsockopt(a,b,c, (const char*) d,e)
14#define recvfrom(a,b,c,d,e,f) recvfrom(a, (char *) b, c, d, e, f)
15#define sendto(a,b,c,d,e,f) sendto(a,(const char*) b,c,d,e,f)
16#undef errno
17#define errno GetLastError()
18#endif
19
20#include <fcntl.h>
21
22#ifdef ISDARWIN
23# define socklen_t int
24#endif
25
27 const WvIPPortAddr &_rem) :
28 localaddr(), remaddr(_rem)
29{
30 int x = 1;
31 setfd(socket(PF_INET, SOCK_DGRAM, 0));
32 if (getfd() < 0
33 || setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) < 0)
34 {
35 seterr(errno);
36 return;
37 }
38
40 set_nonblock(true);
41
42 struct sockaddr *sa = _local.sockaddr();
43 if (bind(getfd(), sa, _local.sockaddr_len()))
44 {
45 delete sa;
46 seterr(errno);
47 return;
48 }
49 delete sa;
50
51 struct sockaddr_in nsa;
52 socklen_t nsalen = sizeof(nsa);
53 if (getsockname(getfd(), (sockaddr *)&nsa, &nsalen) < 0)
54 {
55 seterr(errno);
56 return;
57 }
58 localaddr = WvIPPortAddr(&nsa);
59
60 if (WvIPAddr(_rem) != WvIPAddr())
61 {
62 struct sockaddr *sa = _rem.sockaddr();
63 if (connect(getfd(), sa, _rem.sockaddr_len()))
64 {
65 delete sa;
66 seterr(errno);
67 return;
68 }
69 delete sa;
70 }
71}
72
73
74WvUDPStream::~WvUDPStream()
75{
76}
77
78
80{
81 return &remaddr;
82}
83
84
85const WvAddr *WvUDPStream::local() const
86{
87 return &localaddr;
88}
89
90
91size_t WvUDPStream::uread(void *buf, size_t count)
92{
93 if (!isok() || !buf || !count) return 0;
94
95 struct sockaddr_in from;
96 socklen_t fromlen = sizeof(from);
97 int in = recvfrom(getfd(), buf, count, 0, (sockaddr *)&from, &fromlen);
98
99 if (in >= 0)
100 remaddr = WvIPPortAddr(&from);
101
102 // errors in UDP are ignored
103 return in < 0 ? 0 : in;
104}
105
106
107size_t WvUDPStream::uwrite(const void *buf, size_t count)
108{
109 if (!isok() || !buf || !count) return 0;
110
111 // pretend everything worked if there is nowhere to send data
112 if (remaddr.is_zero()) return count;
113
114 struct sockaddr *to = remaddr.sockaddr();
115 size_t tolen = remaddr.sockaddr_len();
116 int out;
117
118 out = sendto(getfd(), buf, count, 0, to, tolen);
119
120 if (out < 0 && errno == EACCES) // permission denied
121 seterr(EACCES);
122
123 delete to;
124
125 // errors in UDP are ignored
126 // pretend that the write always succeeds even if the kernel
127 // complains since we don't want datagrams backing up in the
128 // buffer and forming merged datagrams as a result
129 return out < 0 ? 0 : out;
130}
131
132
133void WvUDPStream::enable_broadcasts()
134{
135 int value = 1;
136
137 if (!isok()) return;
138
139 setsockopt(getfd(), SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
140}
Base class for different address types, each of which will have the ability to convert itself to/from...
Definition wvaddr.h:119
void setfd(int fd)
Sets the file descriptor for both reading and writing.
Definition wvfdstream.h:36
int getfd() const
Returns the Unix file descriptor for reading and writing.
Definition wvfdstream.h:81
virtual bool isok() const
return true if the stream is actually usable right now
void set_nonblock(bool nonblock)
Make the fds on this stream blocking or non-blocking.
Definition wvfdstream.cc:97
void set_close_on_exec(bool close_on_exec)
Make the fds on this stream close-on-exec or not.
An IP address is made up of a "dotted quad" – four decimal numbers in the form www....
Definition wvaddr.h:250
An IP+Port address also includes a port number, with the resulting form www.xxx.yyy....
Definition wvaddr.h:394
virtual void seterr(int _errnum)
Override seterr() from WvError so that it auto-closes the stream.
Definition wvstream.cc:451
WvUDPStream(const WvIPPortAddr &_local, const WvIPPortAddr &_rem)
connect a new socket
Definition wvudp.cc:26
virtual size_t uread(void *buf, size_t count)
unbuffered I/O functions; these ignore the buffer, which is handled by read().
Definition wvudp.cc:91
virtual const WvAddr * src() const
return the remote address (source of incoming packets, target of outgoing packets).
Definition wvudp.cc:79
virtual size_t uwrite(const void *buf, size_t count)
unbuffered I/O functions; these ignore the buffer, which is handled by write().
Definition wvudp.cc:107