2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * WvUDPStream can send and receive packets on a connectionless UDP socket.
6 * See wvudp.h for details.
11 #include <sys/socket.h>
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)
17 #define errno GetLastError()
23 # define socklen_t int
26 WvUDPStream::WvUDPStream(const WvIPPortAddr
&_local
,
27 const WvIPPortAddr
&_rem
) :
28 localaddr(), remaddr(_rem
)
31 setfd(socket(PF_INET
, SOCK_DGRAM
, 0));
33 || setsockopt(getfd(), SOL_SOCKET
, SO_REUSEADDR
, &x
, sizeof(x
)) < 0)
39 set_close_on_exec(true);
42 struct sockaddr
*sa
= _local
.sockaddr();
43 if (bind(getfd(), sa
, _local
.sockaddr_len()))
51 struct sockaddr_in nsa
;
52 socklen_t nsalen
= sizeof(nsa
);
53 if (getsockname(getfd(), (sockaddr
*)&nsa
, &nsalen
) < 0)
58 localaddr
= WvIPPortAddr(&nsa
);
60 if (WvIPAddr(_rem
) != WvIPAddr())
62 struct sockaddr
*sa
= _rem
.sockaddr();
63 if (connect(getfd(), sa
, _rem
.sockaddr_len()))
74 WvUDPStream::~WvUDPStream()
79 const WvAddr
*WvUDPStream::src() const
85 const WvAddr
*WvUDPStream::local() const
91 size_t WvUDPStream::uread(void *buf
, size_t count
)
93 if (!isok() || !buf
|| !count
) return 0;
95 struct sockaddr_in from
;
96 socklen_t fromlen
= sizeof(from
);
97 int in
= recvfrom(getfd(), buf
, count
, 0, (sockaddr
*)&from
, &fromlen
);
100 remaddr
= WvIPPortAddr(&from
);
102 // errors in UDP are ignored
103 return in
< 0 ? 0 : in
;
107 size_t WvUDPStream::uwrite(const void *buf
, size_t count
)
109 if (!isok() || !buf
|| !count
) return 0;
111 // pretend everything worked if there is nowhere to send data
112 if (remaddr
.is_zero()) return count
;
114 struct sockaddr
*to
= remaddr
.sockaddr();
115 size_t tolen
= remaddr
.sockaddr_len();
118 out
= sendto(getfd(), buf
, count
, 0, to
, tolen
);
120 if (out
< 0 && errno
== EACCES
) // permission denied
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
;
133 void WvUDPStream::enable_broadcasts()
139 setsockopt(getfd(), SOL_SOCKET
, SO_BROADCAST
, &value
, sizeof(value
));