reworking queues
[swift-upb.git] / datagram.h
1 /*
2  *  datagram.h
3  *  serp++
4  *
5  *  Created by Victor Grishchenko, Arno Bakker on 3/9/09.
6  *  Copyright 2009 Delft University of Technology. All rights reserved.
7  *
8  */
9 #ifndef DATAGRAM_H
10 #define DATAGRAM_H
11
12 #ifdef _MSC_VER
13     #include "compat/stdint.h"
14 #else
15     #include <stdint.h>
16 #endif
17 #ifdef _WIN32
18         #include <winsock2.h>
19         #include "compat.h"
20 #else
21     typedef int SOCKET;
22
23     #include <arpa/inet.h>
24     #include <sys/select.h>
25     #include <sys/socket.h>
26     #include <netinet/in.h>
27     #include <unistd.h>
28 #endif
29 #include <stdlib.h>
30 #include <fcntl.h>
31 #include <sys/stat.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <string>
35 #include "hashtree.h"
36 #include "compat/util.h"
37 #include "compat.h"
38
39
40 namespace p2tp {
41
42 #define MAXDGRAMSZ 2800
43 #ifndef _WIN32
44 #define INVALID_SOCKET -1
45 #endif
46
47
48 struct Address {
49     struct sockaddr_in  addr;
50     static uint32_t LOCALHOST;
51     void set_port (uint16_t port) {
52         addr.sin_port = htons(port);
53     }
54     void set_port (const char* port_str) {
55         int p;
56         if (sscanf(port_str,"%i",&p))
57             set_port(p);
58     }
59     void set_ipv4 (uint32_t ipv4) {
60         addr.sin_addr.s_addr = htonl(ipv4);
61     }
62     void set_ipv4 (const char* ipv4_str) ;
63     //{    inet_aton(ipv4_str,&(addr.sin_addr));    }
64     void clear () {
65         memset(&addr,0,sizeof(struct sockaddr_in));
66         addr.sin_family = AF_INET;
67     }
68     Address() {
69         clear();
70     }
71     Address(const char* ip, uint16_t port)  {
72         clear();
73         set_ipv4(ip);
74         set_port(port);
75     }
76     Address(const char* ip_port);
77     Address(uint16_t port) {
78         clear();
79         set_ipv4(LOCALHOST);
80         set_port(port);
81     }
82     Address(uint32_t ipv4addr, uint16_t port) {
83         clear();
84         set_ipv4(ipv4addr);
85         set_port(port);
86     }
87     Address(const struct sockaddr_in& address) : addr(address) {}
88     uint32_t ipv4 () const { return ntohl(addr.sin_addr.s_addr); }
89     uint16_t port () const { return ntohs(addr.sin_port); }
90     operator sockaddr_in () const {return addr;}
91     bool operator == (const Address& b) const {
92         return addr.sin_family==b.addr.sin_family &&
93         addr.sin_port==b.addr.sin_port &&
94         addr.sin_addr.s_addr==b.addr.sin_addr.s_addr;
95     }
96     const char* str () const {
97         static char rs[4][32];
98         static int i;
99         i = (i+1) & 3;
100         sprintf(rs[i],"%i.%i.%i.%i:%i",ipv4()>>24,(ipv4()>>16)&0xff,
101                 (ipv4()>>8)&0xff,ipv4()&0xff,port());
102         return rs[i];
103     }
104     bool operator != (const Address& b) const { return !(*this==b); }
105 };
106
107
108 struct Datagram {
109
110         Address addr;
111         SOCKET sock;
112         int offset, length;
113         uint8_t buf[MAXDGRAMSZ*2];
114
115         static SOCKET Bind(Address address);
116         static void Close(int port);
117         static tint Time();
118         static SOCKET Wait (int sockcnt, SOCKET* sockets, tint usec=0);
119         static tint now, epoch, start;
120     static uint64_t dgrams_up, dgrams_down, bytes_up, bytes_down;
121
122         Datagram (SOCKET socket, const Address addr_) : addr(addr_), offset(0),
123                 length(0), sock(socket) {}
124         Datagram (SOCKET socket) : offset(0), length(0), sock(socket) {
125         }
126
127         int space () const { return MAXDGRAMSZ-length; }
128         int size() const { return length-offset; }
129         std::string str() const { return std::string((char*)buf+offset,size()); }
130     const uint8_t* operator * () const { return buf+offset; }
131
132         int Push (const uint8_t* data, int l) { // scatter-gather one day
133                 int toc = l<space() ? l : space();
134                 memcpy(buf+length,data,toc);
135                 length += toc;
136                 return toc;
137         }
138         int Pull (uint8_t** data, int l) {
139                 int toc = l<size() ? l : size();
140                 //memcpy(data,buf+offset,toc);
141                 *data = buf+offset;
142                 offset += toc;
143                 return toc;
144         }
145
146         int Send ();
147         int Recv ();
148         const Address& address() const { return addr; }
149     void Clear() { offset=length=0; }
150
151         void    PushString (std::string str) {
152                 Push((uint8_t*)str.c_str(),str.size());
153         }
154         void    Push8 (uint8_t b) {
155                 buf[length++] = b;
156         }
157         void    Push16 (uint16_t w) {
158                 *(uint16_t*)(buf+length) = htons(w);
159                 length+=2;
160         }
161         void    Push32 (uint32_t i) {
162                 *(uint32_t*)(buf+length) = htonl(i);
163                 length+=4;
164         }
165         void    Push64 (uint64_t l) {
166                 *(uint32_t*)(buf+length) = htonl((uint32_t)(l>>32));
167                 *(uint32_t*)(buf+length+4) = htonl((uint32_t)(l&0xffffffff));
168                 length+=8;
169         }
170         void    PushHash (const Sha1Hash& hash) {
171                 Push((uint8_t*)hash.bits, Sha1Hash::SIZE);
172         }
173
174         uint8_t Pull8() {
175                 if (size()<1) return 0;
176                 return buf[offset++];
177         }
178         uint16_t Pull16() {
179                 if (size()<2) return 0;
180                 offset+=2;
181                 return ntohs(*(uint16_t*)(buf+offset-2));
182         }
183         uint32_t Pull32() {
184                 if (size()<4) return 0;
185                 uint32_t i = ntohl(*(uint32_t*)(buf+offset));
186                 offset+=4;
187                 return i;
188         }
189         uint64_t Pull64() {
190                 if (size()<8) return 0;
191                 uint64_t l = ntohl(*(uint32_t*)(buf+offset));
192                 l<<=32;
193                 l |= ntohl(*(uint32_t*)(buf+offset+4));
194                 offset+=8;
195                 return l;
196         }
197         Sha1Hash PullHash() {
198                 if (size()<Sha1Hash::SIZE) return Sha1Hash::ZERO;
199                 offset += Sha1Hash::SIZE;
200                 return Sha1Hash(false,(char*)buf+offset-Sha1Hash::SIZE);
201         }
202         //std::string   to_string () const ;
203
204 };
205
206 const char* tintstr(tint t=0);
207 std::string sock2str (struct sockaddr_in addr);
208 #ifdef DEBUG
209 #define dprintf(...) printf(__VA_ARGS__)
210 #else
211 #define dprintf(...) {}
212 #endif
213 #define eprintf(...) fprintf(stderr,__VA_ARGS__)
214 //#define dprintf(...) {}
215
216 }
217
218 #endif