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