diff options
Diffstat (limited to 'src/nat/gnunet-service-nat_stun.c')
-rw-r--r-- | src/nat/gnunet-service-nat_stun.c | 171 |
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 | */ |
50 | struct StunState { | 50 | struct 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 | */ |
66 | static int | 67 | static int |
67 | stun_get_mapped(struct StunState *st, | 68 | stun_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 | */ |
123 | int | 124 | int |
124 | GNUNET_NAT_stun_handle_packet_(const void *data, | 125 | GNUNET_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 | ||