5 * Created by Victor Grishchenko on 3/9/09.
6 * Copyright 2009 Delft Technical University. All rights reserved.
10 #include <glog/logging.h>
15 tint Datagram::now = Datagram::Time();
17 int Datagram::Send () {
18 int r = sendto(sock,buf+offset,length-offset,0,
19 (struct sockaddr*)&(addr),sizeof(struct sockaddr_in));
26 int Datagram::Recv () {
27 socklen_t addrlen = sizeof(struct sockaddr_in);
29 length = recvfrom (sock, buf, MAXDGRAMSZ, 0,
30 (struct sockaddr*)&(addr), &addrlen);
32 PLOG(ERROR)<<"on recv";
38 int Datagram::Wait (int sockcnt, int* sockets, tint usec) {
39 LOG(INFO)<<"waiting for "<<sockcnt;
40 struct timeval timeout;
41 timeout.tv_sec = usec/SEC;
42 timeout.tv_usec = usec%SEC;
47 for(int i=0; i<sockcnt; i++) {
48 FD_SET(sockets[i],&bases);
49 FD_SET(sockets[i],&err);
50 if (sockets[i]>max_sock_fd)
51 max_sock_fd = sockets[i];
53 int sel = select(max_sock_fd+1, &bases, NULL, &err, &timeout);
55 for (int i=0; i<=sockcnt; i++)
56 if (FD_ISSET(sockets[i],&bases))
59 PLOG(ERROR)<<"select fails";
63 tint Datagram::Time () {
65 gettimeofday(&t,NULL);
70 //DLOG(INFO)<<"now is "<<ret;
74 int Datagram::Bind (int portno) {
75 struct sockaddr_in addr;
76 int fd, len = sizeof(struct sockaddr_in),
77 sndbuf=1<<20, rcvbuf=1<<20;
78 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
79 PLOG(ERROR)<<"socket fails";
82 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
84 if ( setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(int)) < 0 ) {
85 PLOG(ERROR)<<"setsockopt fails";
88 if ( setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(int)) < 0 ) {
89 PLOG(ERROR)<<"setsockopt2 fails";
92 printf("BUFS: %i %i\n",sndbuf,rcvbuf);
93 memset(&addr, 0, sizeof(struct sockaddr_in));
94 addr.sin_family = AF_INET;
95 addr.sin_port = htons(portno);
96 addr.sin_addr.s_addr = INADDR_ANY;
97 if (::bind(fd, (struct sockaddr*)&addr, len) != 0) {
98 PLOG(ERROR)<<"bind fails";
104 void Datagram::Close (int sock) { // remove from fd_set
105 if (::close(sock)!=0)
106 PLOG(ERROR)<<"on closing a socket";
110 std::string sock2str (struct sockaddr_in addr) {
112 inet_ntop(AF_INET,&(addr.sin_addr),ipch,32);
113 sprintf(ipch+strlen(ipch),":%i",ntohs(addr.sin_port));
114 return std::string(ipch);
118 std::string Datagram::to_string () const { // TODO: pretty-print P2TP
119 std::string addrs = sock2str(addr);
120 char hex[MAXDGRAMSZ*2];
121 for(int i=offset; i<length; i++)
122 sprintf(hex+i*2,"%02x",buf[i]);
123 std::string hexs(hex+offset*2,(length-offset)*2);
124 return addrs + '\t' + hexs;