- Result of svn merge -x --ignore-eol-style -r 424:458 https://ttuki.vtt.fi/svn/p2p...
[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 _MSC_VER
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 #define MAXDGRAMSZ 1400
38 #ifndef _MSC_VER
39 #define INVALID_SOCKET -1
40 #endif
41
42 struct Datagram {
43
44     struct Address {
45         struct sockaddr_in  addr;
46         static uint32_t LOCALHOST;
47         void init(uint32_t ipv4=0, uint16_t port=0) {
48             memset(&addr,0,sizeof(struct sockaddr_in));
49             addr.sin_family = AF_INET;
50             addr.sin_port = htons(port);
51             addr.sin_addr.s_addr = htonl(ipv4);
52         }
53         Address() { init(); }
54         Address(const char* ip, uint16_t port) {
55             init(LOCALHOST,port);
56             inet_aton(ip,&(addr.sin_addr));
57         }
58         Address(uint16_t port) {
59             init(LOCALHOST,port);
60         }
61         Address(uint32_t ipv4addr, uint16_t port) {
62             init(ipv4addr,port);
63         }
64         Address(const struct sockaddr_in& address) : addr(address) {}
65         operator sockaddr_in () const {return addr;}
66         bool operator == (const Address& b) {
67             return addr.sin_family==b.addr.sin_family &&
68             addr.sin_port==b.addr.sin_port &&
69             addr.sin_addr.s_addr==b.addr.sin_addr.s_addr;
70         }
71         bool operator != (const Address& b) { return !(*this==b); }
72     };
73
74         Address addr;
75         SOCKET sock;
76         int offset, length;
77         uint8_t buf[MAXDGRAMSZ*2];
78
79         static SOCKET Bind(Address address);
80         static void Close(int port);
81         static tint Time();
82         static SOCKET Wait (int sockcnt, SOCKET* sockets, tint usec=0);
83         static tint now;
84
85         Datagram (SOCKET socket, const Address addr_) : addr(addr_), offset(0),
86                 length(0), sock(socket) {}
87         Datagram (SOCKET socket) : offset(0), length(0), sock(socket) {
88         }
89
90         int space () const { return MAXDGRAMSZ-length; }
91         int size() const { return length-offset; }
92         std::string str() const { return std::string((char*)buf+offset,size()); }
93     const uint8_t* operator * () const { return buf+offset; }
94
95         int Push (const uint8_t* data, int l) { // scatter-gather one day
96                 int toc = l<space() ? l : space();
97                 memcpy(buf+length,data,toc);
98                 length += toc;
99                 return toc;
100         }
101         int Pull (uint8_t** data, int l) {
102                 int toc = l<size() ? l : size();
103                 //memcpy(data,buf+offset,toc);
104                 *data = buf+offset;
105                 offset += toc;
106                 return toc;
107         }
108
109         int Send ();
110         int Recv ();
111         const Address& address() const { return addr; }
112     void Clear() { offset=length=0; }
113
114         void    PushString (std::string str) {
115                 Push((uint8_t*)str.c_str(),str.size());
116         }
117         void    Push8 (uint8_t b) {
118                 buf[length++] = b;
119         }
120         void    Push16 (uint16_t w) {
121                 *(uint16_t*)(buf+length) = htons(w);
122                 length+=2;
123         }
124         void    Push32 (uint32_t i) {
125                 *(uint32_t*)(buf+length) = htonl(i);
126                 length+=4;
127         }
128         void    Push64 (uint64_t l) {
129                 *(uint32_t*)(buf+length) = htonl((uint32_t)(l>>32));
130                 *(uint32_t*)(buf+length+4) = htonl((uint32_t)(l&0xffffffff));
131                 length+=8;
132         }
133         void    PushHash (const Sha1Hash& hash) {
134                 Push(hash.bits, Sha1Hash::SIZE);
135         }
136
137         uint8_t Pull8() {
138                 if (size()<1) return 0;
139                 return buf[offset++];
140         }
141         uint16_t Pull16() {
142                 if (size()<2) return 0;
143                 offset+=2;
144                 return ntohs(*(uint16_t*)(buf+offset-2));
145         }
146         uint32_t Pull32() {
147                 if (size()<4) return 0;
148                 uint32_t i = ntohl(*(uint32_t*)(buf+offset));
149                 offset+=4;
150                 return i;
151         }
152         uint64_t Pull64() {
153                 if (size()<8) return 0;
154                 uint64_t l = ntohl(*(uint32_t*)(buf+offset));
155                 l<<=32;
156                 l |= ntohl(*(uint32_t*)(buf+offset+4));
157                 offset+=8;
158                 return l;
159         }
160         Sha1Hash PullHash() {
161                 if (size()<Sha1Hash::SIZE) return Sha1Hash::ZERO;
162                 offset += Sha1Hash::SIZE;
163                 return Sha1Hash(false,(char*)buf+offset-Sha1Hash::SIZE);
164         }
165         //std::string   to_string () const ;
166
167 };
168
169 std::string sock2str (struct sockaddr_in addr);
170
171 }
172
173 #endif