aboutsummaryrefslogtreecommitdiff
path: root/src/nat/gnunet-service-nat_stun.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat/gnunet-service-nat_stun.c')
-rw-r--r--src/nat/gnunet-service-nat_stun.c171
1 files changed, 86 insertions, 85 deletions
diff --git a/src/nat/gnunet-service-nat_stun.c b/src/nat/gnunet-service-nat_stun.c
index d8b791d0a..8a5311254 100644
--- a/src/nat/gnunet-service-nat_stun.c
+++ b/src/nat/gnunet-service-nat_stun.c
@@ -40,14 +40,15 @@
40#include "gnunet_util_lib.h" 40#include "gnunet_util_lib.h"
41#include "nat_stun.h" 41#include "nat_stun.h"
42 42
43#define LOG(kind, ...) GNUNET_log_from(kind, "stun", __VA_ARGS__) 43#define LOG(kind, ...) GNUNET_log_from (kind, "stun", __VA_ARGS__)
44 44
45 45
46/** 46/**
47 * Context for #stun_get_mapped(). 47 * Context for #stun_get_mapped().
48 * Used to store state across processing attributes. 48 * Used to store state across processing attributes.
49 */ 49 */
50struct StunState { 50struct StunState
51{
51 uint16_t attr; 52 uint16_t attr;
52}; 53};
53 54
@@ -64,44 +65,44 @@ struct StunState {
64 * @return #GNUNET_OK if @a arg was initialized 65 * @return #GNUNET_OK if @a arg was initialized
65 */ 66 */
66static int 67static int
67stun_get_mapped(struct StunState *st, 68stun_get_mapped (struct StunState *st,
68 const struct stun_attr *attr, 69 const struct stun_attr *attr,
69 uint32_t magic, 70 uint32_t magic,
70 struct sockaddr_in *arg) 71 struct sockaddr_in *arg)
71{ 72{
72 const struct stun_addr *returned_addr; 73 const struct stun_addr *returned_addr;
73 struct sockaddr_in *sa = (struct sockaddr_in *)arg; 74 struct sockaddr_in *sa = (struct sockaddr_in *) arg;
74 uint16_t type = ntohs(attr->attr); 75 uint16_t type = ntohs (attr->attr);
75 76
76 switch (type) 77 switch (type)
77 { 78 {
78 case STUN_MAPPED_ADDRESS: 79 case STUN_MAPPED_ADDRESS:
79 if ((st->attr == STUN_XOR_MAPPED_ADDRESS) || 80 if ((st->attr == STUN_XOR_MAPPED_ADDRESS) ||
80 (st->attr == STUN_MS_XOR_MAPPED_ADDRESS)) 81 (st->attr == STUN_MS_XOR_MAPPED_ADDRESS))
81 return GNUNET_NO; 82 return GNUNET_NO;
82 magic = 0; 83 magic = 0;
83 break; 84 break;
84 85
85 case STUN_MS_XOR_MAPPED_ADDRESS: 86 case STUN_MS_XOR_MAPPED_ADDRESS:
86 if (st->attr == STUN_XOR_MAPPED_ADDRESS) 87 if (st->attr == STUN_XOR_MAPPED_ADDRESS)
87 return GNUNET_NO; 88 return GNUNET_NO;
88 break; 89 break;
89 90
90 case STUN_XOR_MAPPED_ADDRESS: 91 case STUN_XOR_MAPPED_ADDRESS:
91 break; 92 break;
92 93
93 default: 94 default:
94 return GNUNET_NO; 95 return GNUNET_NO;
95 } 96 }
96 97
97 if (ntohs(attr->len) < sizeof(struct stun_addr)) 98 if (ntohs (attr->len) < sizeof(struct stun_addr))
98 return GNUNET_NO; 99 return GNUNET_NO;
99 returned_addr = (const struct stun_addr *)(attr + 1); 100 returned_addr = (const struct stun_addr *) (attr + 1);
100 if (AF_INET != returned_addr->family) 101 if (AF_INET != returned_addr->family)
101 return GNUNET_NO; 102 return GNUNET_NO;
102 st->attr = type; 103 st->attr = type;
103 sa->sin_family = AF_INET; 104 sa->sin_family = AF_INET;
104 sa->sin_port = returned_addr->port ^ htons(ntohl(magic) >> 16); 105 sa->sin_port = returned_addr->port ^ htons (ntohl (magic) >> 16);
105 sa->sin_addr.s_addr = returned_addr->addr ^ magic; 106 sa->sin_addr.s_addr = returned_addr->addr ^ magic;
106 return GNUNET_OK; 107 return GNUNET_OK;
107} 108}
@@ -121,9 +122,9 @@ stun_get_mapped(struct StunState *st,
121 * #GNUNET_NO if the packet is invalid (not a stun packet) 122 * #GNUNET_NO if the packet is invalid (not a stun packet)
122 */ 123 */
123int 124int
124GNUNET_NAT_stun_handle_packet_(const void *data, 125GNUNET_NAT_stun_handle_packet_ (const void *data,
125 size_t len, 126 size_t len,
126 struct sockaddr_in *arg) 127 struct sockaddr_in *arg)
127{ 128{
128 const struct stun_header *hdr; 129 const struct stun_header *hdr;
129 const struct stun_attr *attr; 130 const struct stun_attr *attr;
@@ -137,76 +138,76 @@ GNUNET_NAT_stun_handle_packet_(const void *data,
137 * while 'data' is advanced accordingly. 138 * while 'data' is advanced accordingly.
138 */ 139 */
139 if (len < sizeof(struct stun_header)) 140 if (len < sizeof(struct stun_header))
140 { 141 {
141 LOG(GNUNET_ERROR_TYPE_DEBUG, 142 LOG (GNUNET_ERROR_TYPE_DEBUG,
142 "Packet too short to be a STUN packet\n"); 143 "Packet too short to be a STUN packet\n");
143 return GNUNET_NO; 144 return GNUNET_NO;
144 } 145 }
145 hdr = data; 146 hdr = data;
146 /* Skip header as it is already in hdr */ 147 /* Skip header as it is already in hdr */
147 len -= sizeof(struct stun_header); 148 len -= sizeof(struct stun_header);
148 data += sizeof(struct stun_header); 149 data += sizeof(struct stun_header);
149 150
150 /* len as advertised in the message */ 151 /* len as advertised in the message */
151 advertised_message_size = ntohs(hdr->msglen); 152 advertised_message_size = ntohs (hdr->msglen);
152 message_magic_cookie = ntohl(hdr->magic); 153 message_magic_cookie = ntohl (hdr->magic);
153 /* Compare if the cookie match */ 154 /* Compare if the cookie match */
154 if (STUN_MAGIC_COOKIE != message_magic_cookie) 155 if (STUN_MAGIC_COOKIE != message_magic_cookie)
155 { 156 {
156 LOG(GNUNET_ERROR_TYPE_DEBUG, 157 LOG (GNUNET_ERROR_TYPE_DEBUG,
157 "Invalid magic cookie for STUN packet\n"); 158 "Invalid magic cookie for STUN packet\n");
158 return GNUNET_NO; 159 return GNUNET_NO;
159 } 160 }
160 161
161 LOG(GNUNET_ERROR_TYPE_INFO, 162 LOG (GNUNET_ERROR_TYPE_INFO,
162 "STUN Packet, msg %s (%04x), length: %d\n", 163 "STUN Packet, msg %s (%04x), length: %d\n",
163 stun_msg2str(ntohs(hdr->msgtype)), 164 stun_msg2str (ntohs (hdr->msgtype)),
164 ntohs(hdr->msgtype), 165 ntohs (hdr->msgtype),
165 advertised_message_size); 166 advertised_message_size);
166 if (advertised_message_size > len) 167 if (advertised_message_size > len)
167 { 168 {
168 LOG(GNUNET_ERROR_TYPE_INFO, 169 LOG (GNUNET_ERROR_TYPE_INFO,
169 "Scrambled STUN packet length (got %d, expecting %d)\n", 170 "Scrambled STUN packet length (got %d, expecting %d)\n",
170 advertised_message_size, 171 advertised_message_size,
171 (int)len); 172 (int) len);
172 return GNUNET_NO; 173 return GNUNET_NO;
173 } 174 }
174 len = advertised_message_size; 175 len = advertised_message_size;
175 memset(&st, 0, sizeof(st)); 176 memset (&st, 0, sizeof(st));
176 177
177 while (len > 0) 178 while (len > 0)
179 {
180 if (len < sizeof(struct stun_attr))
178 { 181 {
179 if (len < sizeof(struct stun_attr)) 182 LOG (GNUNET_ERROR_TYPE_INFO,
180 { 183 "Attribute too short (got %d, expecting %d)\n",
181 LOG(GNUNET_ERROR_TYPE_INFO, 184 (int) len,
182 "Attribute too short (got %d, expecting %d)\n", 185 (int) sizeof(struct stun_attr));
183 (int)len, 186 break;
184 (int)sizeof(struct stun_attr)); 187 }
185 break; 188 attr = (const struct stun_attr *) data;
186 } 189
187 attr = (const struct stun_attr *)data; 190 /* compute total attribute length */
188 191 advertised_message_size = ntohs (attr->len) + sizeof(struct stun_attr);
189 /* compute total attribute length */ 192
190 advertised_message_size = ntohs(attr->len) + sizeof(struct stun_attr); 193 /* Check if we still have space in our buffer */
191 194 if (advertised_message_size > len)
192 /* Check if we still have space in our buffer */ 195 {
193 if (advertised_message_size > len) 196 LOG (GNUNET_ERROR_TYPE_INFO,
194 { 197 "Inconsistent attribute (length %d exceeds remaining msg len %d)\n",
195 LOG(GNUNET_ERROR_TYPE_INFO, 198 advertised_message_size,
196 "Inconsistent attribute (length %d exceeds remaining msg len %d)\n", 199 (int) len);
197 advertised_message_size, 200 break;
198 (int)len);
199 break;
200 }
201 if (GNUNET_OK ==
202 stun_get_mapped(&st,
203 attr,
204 hdr->magic,
205 arg))
206 ret = GNUNET_OK;
207 data += advertised_message_size;
208 len -= advertised_message_size;
209 } 201 }
202 if (GNUNET_OK ==
203 stun_get_mapped (&st,
204 attr,
205 hdr->magic,
206 arg))
207 ret = GNUNET_OK;
208 data += advertised_message_size;
209 len -= advertised_message_size;
210 }
210 return ret; 211 return ret;
211} 212}
212 213