/* * Worldvisions Weaver Software: * Copyright (C) 1997-2002 Net Integration Technologies, Inc. * * UDP test program. I don't think this works... */ #include "wvistreamlist.h" #include "wvlog.h" #include "wvipraw.h" #include "wvhashtable.h" #include DeclareWvList(WvInPlaceBuf); class WvIPRawListener; class WvIPRawConn : public WvStream { friend class WvIPRawListener; public: WvIPRawConn(WvIPRawListener *_parent, const WvIPAddr &_remaddr); WvIPAddr remaddr; protected: WvIPRawListener *parent; time_t last_receive; WvInPlaceBufList buflist; virtual bool isok() const; virtual size_t uread(void *buf, size_t size); virtual size_t uwrite(const void *buf, size_t size); void push(const void *buf, size_t size); }; DeclareWvDict(WvIPRawConn, WvIPAddr, remaddr); class WvIPRawListener : public WvIPRawStream { friend class WvIPRawConn; WvIPRawConnDict connlist; public: WvIPRawListener(const WvIPAddr &_localaddr); virtual void execute(); }; WvIPRawConn::WvIPRawConn(WvIPRawListener *_parent, const WvIPAddr &_remaddr) : remaddr(_remaddr) { parent = _parent; time(&last_receive); } bool WvIPRawConn::isok() const { return parent->connlist[remaddr] == this; } size_t WvIPRawConn::uread(void *buf, size_t size) { if (!buflist.count()) return 0; WvInPlaceBufList::Iter i(buflist); i.rewind(); i.next(); WvInPlaceBuf &b = *i; if (b.used() < size) size = b.used(); memcpy(buf, b.get(size), size); i.unlink(); return size; } size_t WvIPRawConn::uwrite(const void *buf, size_t size) { parent->setdest(remaddr); return parent->write(buf, size); } void WvIPRawConn::push(const void *buf, size_t size) { time(&last_receive); WvInPlaceBuf *b = new WvInPlaceBuf(size); b->put(buf, size); buflist.append(b, true); } WvIPRawListener::WvIPRawListener(const WvIPAddr &_localaddr) : WvIPRawStream(_localaddr, WvIPAddr()), connlist(7) { } void WvIPRawListener::execute() { WvIPRawStream::execute(); unsigned char buf[2048]; // larger than an expected UDP packet size_t len; while (select(0)) { len = read(buf, sizeof(buf)); if (!len) continue; WvIPRawConn *conn = connlist[*(WvIPAddr *)src()]; if (!conn) { conn = new WvIPRawConn(this, *(WvIPAddr *)src()); connlist.add(conn, true); } conn->push(buf, len); } } int main(int argc, char **argv) { WvLog err("ip2test", WvLog::Error); WvIPAddr localaddr(argc > 1 ? argv[1] : "0.0.0.0"); WvIPRawListener sock(localaddr); err(WvLog::Info, "Local address is %s.\n", localaddr); wvcon->autoforward(sock); sock.autoforward(err); WvIStreamList l; l.append(wvcon, false, "wvcon"); l.append(&sock, false, "socket"); #if 0 // not done yet while (wvcon->isok() && sock.isok()) { sock.setdest(remaddr); if (l.select(1000)) { if (wvcon->select(0)) wvcon->callback(); else if (sock.select(0)) { sock.callback(); err(WvLog::Info, " (remote: %s)\n", *sock.src()); } } } #endif if (!wvcon->isok() && wvcon->geterr()) err("stdin: %s\n", strerror(wvcon->geterr())); else if (!sock.isok() && sock.geterr()) err("socket: %s\n", strerror(sock.geterr())); return 0; }