]> git.vomp.tv Git - vompserver.git/blob - dsock.c
Initial import
[vompserver.git] / dsock.c
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "dsock.h"
22
23 DatagramSocket::DatagramSocket(short port)
24 {
25   myPort = port;
26   addrlen = sizeof(struct sockaddr);
27
28   if ((socketnum = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
29   { perror("socket"); exit(1); }
30
31   myAddr.sin_family = AF_INET;         // host byte order
32   myAddr.sin_port = htons(myPort);     // short, network byte order
33   myAddr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP
34   memset(&(myAddr.sin_zero), 0, 8);    // zero the rest of the struct
35   if (bind(socketnum, (struct sockaddr *)&myAddr, addrlen) == -1)
36   { perror("bind"); printf(" %s ", strerror(errno)); exit(1); }
37
38   FD_ZERO(&readfds);
39   FD_SET(socketnum, &readfds);
40   tv.tv_sec = 0;
41   tv.tv_usec = 0;
42 }
43
44 DatagramSocket::~DatagramSocket()
45 {
46   close(socketnum);
47 }
48
49 unsigned char DatagramSocket::waitforMessage(unsigned char how)
50 {
51   /* how = 0 - block
52      how = 1 - start new wait
53      how = 2 - continue wait
54   */
55
56   struct timeval* passToSelect = NULL;
57
58
59   if (how == 0)
60   {
61     passToSelect = NULL;
62   }
63   else if (how == 1)
64   {
65     tv.tv_sec = 1;
66     tv.tv_usec = 100000;
67     passToSelect = &tv;
68   }
69   else if (how == 2)
70   {
71     if ((tv.tv_sec == 0) && (tv.tv_usec == 0))  // protection in case timer = 0
72     {
73       tv.tv_sec = 1;
74       tv.tv_usec = 100000;
75     }
76     passToSelect = &tv;
77   }
78   FD_ZERO(&readfds);
79   FD_SET(socketnum, &readfds);
80
81   if (select(socketnum + 1, &readfds, NULL, NULL, passToSelect) <= 0)
82   {  return 1;  }
83
84   if ((mlength = recvfrom(socketnum, buf, MAXBUFLEN, 0,
85       (struct sockaddr *)&theirAddr, &addrlen)) == -1)
86   { perror("recvfrom"); return 0; }
87   else
88   {
89     memset(&buf[mlength], 0, MAXBUFLEN - mlength);
90     strcpy(fromIPA, inet_ntoa(theirAddr.sin_addr));
91     fromPort = ntohs(theirAddr.sin_port);
92
93     if (DSOCKDEBUG)
94     {
95       printf("%s:%i\tIN  %i\t", fromIPA, fromPort, mlength);
96       int k;
97       for(k = 0; k < mlength; k++)
98         printf("%u ", (unsigned char)buf[k]);
99       printf("\n");
100     }
101     return 2;
102   }
103
104   /* Return 0, failure
105      Return 1, nothing happened, timer expired
106      Return 2, packet arrived (timer not expired)
107   */
108 }
109
110 int DatagramSocket::getDataLength(void) const
111 {
112   return mlength;
113 }
114
115 char *DatagramSocket::getData(void)             {  return buf;  }
116 char *DatagramSocket::getFromIPA(void)          {  return fromIPA;  }
117 short DatagramSocket::getFromPort(void) const   {  return fromPort; }
118
119 void DatagramSocket::send(char *ipa, short port, char *message, int length)
120 {
121   if (DSOCKDEBUG)
122   {
123     printf("%s:%i\tOUT %i\t", ipa, port, length);
124     int k;
125     uchar l;
126     for (k = 0; k < length; k++)
127       { l = (uchar)message[k]; printf("%u ", l); }
128   }
129
130   int sentLength = 0;
131
132   theirAddr.sin_family = AF_INET;      // host byte order
133   theirAddr.sin_port = htons(port);    // short, network byte order
134   struct in_addr tad;                  // temp struct tad needed to pass to theirAddr.sin_addr
135   tad.s_addr = inet_addr(ipa);
136   theirAddr.sin_addr = tad;            // address
137   memset(&(theirAddr.sin_zero), 0, 8); // zero the rest of the struct
138
139   unsigned char crypt[MAXBUFLEN];
140   memcpy(crypt, message, length);
141
142   sentLength = sendto(socketnum, crypt, length, 0, (struct sockaddr *)&theirAddr, addrlen);
143   if (sentLength == length)
144   {
145     printf(" GOOD\n");
146   }
147   else
148   {
149     printf(" --BAD--");  fflush(stdout);
150     sentLength = sendto(socketnum, crypt, length, 0, (struct sockaddr *)&theirAddr, addrlen);
151     if (sentLength == length)
152       printf(" GOOD\n");
153     else
154     {
155       printf(" -#-FAILED-#-\n");
156
157       if (DSOCKDEBUG && (sentLength != length))
158       {
159         printf("--------------\n");
160         printf("Sendto failure\n");
161         printf("--------------\n");
162         printf("%s:%i\tOUT %i %i ...\n", ipa, port, length, sentLength);
163         perror("Perror reports");
164         printf("errno value: %d\n", errno);
165         printf("errno translated: %s\n", strerror(errno));
166       //  printf("h_errno value: %d\n", h_errno);
167       //  printf("\nActual address: %s\n", inet_ntoa(tad));
168       //  printf("Actual port: %i\n", ntohs(theirAddr.sin_port));
169         printf("continuing...\n\n");
170       }
171     }
172   }
173 }
174