the Address inner class
[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 Technical University. All rights reserved.
7  *
8  */
9 #ifndef DATAGRAM_H
10 #define DATAGRAM_H
11 #include <stdint.h>
12 #include <stdlib.h>
13 #include <fcntl.h>
14 #include <sys/select.h>
15 #include <sys/stat.h>
16 #include <sys/socket.h>
17 #include <sys/time.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 //#include <sys/mman.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <stdio.h>
24 #include <string>
25 #include "hashtree.h"
26
27 namespace p2tp {
28
29 typedef int64_t tint;
30 #define TINT_SEC ((tint)1000000)
31 #define TINT_MSEC ((tint)1000)
32 #define TINT_uSEC ((tint)1)
33 #define TINT_NEVER ((tint)0x7fffffffffffffffLL)
34 #define MAXDGRAMSZ 1400
35 #define INVALID_SOCKET -1
36     
37     
38 struct Datagram {
39         
40     struct Address {
41         struct sockaddr_in  addr;
42         Address() {
43             memset(&addr,0,sizeof(struct sockaddr_in)); 
44         }
45         Address(const char* ip, uint16_t port) {
46             addr.sin_family = AF_INET;
47             addr.sin_port = htons(port);
48             inet_aton(ip,&(addr.sin_addr));
49         }
50         Address(uint16_t port) {
51             addr.sin_family = AF_INET;
52             addr.sin_port = htons(port);
53             addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
54         }
55         Address(const struct sockaddr_in& address) : addr(address) {}
56         operator sockaddr_in () {return addr;}
57     };
58     
59         Address addr;
60         int sock;
61         int offset, length;
62         uint8_t buf[MAXDGRAMSZ*2];
63     
64         static int Bind(int port);
65         static void Close(int port);
66         static tint Time();
67         static int Wait (int sockcnt, int* sockets, tint usec=0);
68         static tint now;
69         
70         Datagram (int socket, const Address addr_) : addr(addr_), offset(0), 
71                 length(0), sock(socket) {}
72         Datagram (int socket) : offset(0), length(0), sock(socket) { 
73         }
74         
75         int space () const { return MAXDGRAMSZ-length; }
76         int size() const { return length-offset; }
77         std::string str() const { return std::string((char*)buf+offset,size()); }
78     const uint8_t* operator * () const { return buf+offset; }
79         
80         int Push (const uint8_t* data, int l) { // scatter-gather one day
81                 int toc = l<space() ? l : space();
82                 memcpy(buf+length,data,toc);
83                 length += toc;
84                 return toc;
85         }
86         int Pull (uint8_t** data, int l) {
87                 int toc = l<size() ? l : size();
88                 //memcpy(data,buf+offset,toc);
89                 *data = buf+offset;
90                 offset += toc;
91                 return toc;
92         }
93         
94         int Send ();
95         int Recv ();
96         const Address& address() const { return addr; }
97     void Clear() { offset=length=0; }
98
99         void    PushString (std::string str) {
100                 Push((uint8_t*)str.c_str(),str.size());
101         }
102         void    Push8 (uint8_t b) {
103                 buf[length++] = b;
104         }
105         void    Push16 (uint16_t w) {
106                 *(uint16_t*)(buf+length) = htons(w);
107                 length+=2;
108         }
109         void    Push32 (uint32_t i) {
110                 *(uint32_t*)(buf+length) = htonl(i);
111                 length+=4;
112         }
113         void    Push64 (uint64_t l) {
114                 *(uint32_t*)(buf+length) = htonl((uint32_t)(l>>32));
115                 *(uint32_t*)(buf+length+4) = htonl((uint32_t)(l&0xffffffff));
116                 length+=8;
117         }
118         void    PushHash (const Sha1Hash& hash) {
119                 Push(hash.bits, Sha1Hash::SIZE);
120         }
121         
122         uint8_t Pull8() {
123                 if (size()<1) return 0;
124                 return buf[offset++];
125         }
126         uint16_t Pull16() {
127                 if (size()<2) return 0;
128                 offset+=2;
129                 return ntohs(*(uint16_t*)(buf+offset-2));
130         }
131         uint32_t Pull32() {
132                 if (size()<4) return 0;
133                 uint32_t i = ntohl(*(uint32_t*)(buf+offset));
134                 offset+=4;
135                 return i;
136         }
137         uint64_t Pull64() {
138                 if (size()<8) return 0;
139                 uint64_t l = ntohl(*(uint32_t*)(buf+offset));
140                 l<<=32;
141                 l |= ntohl(*(uint32_t*)(buf+offset+4));
142                 offset+=8;
143                 return l;
144         }
145         Sha1Hash PullHash() {
146                 if (size()<Sha1Hash::SIZE) return Sha1Hash::ZERO;
147                 offset += Sha1Hash::SIZE;
148                 return Sha1Hash(false,(char*)buf+offset-Sha1Hash::SIZE);
149         }
150         //std::string   to_string () const ;
151         
152 };
153
154 std::string sock2str (struct sockaddr_in addr);
155
156 }
157
158 #endif