Changeset 1812a0d in mainline
- Timestamp:
- 2011-11-23T19:06:15Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 762b48a
- Parents:
- 6896409c
- Location:
- uspace/srv/net/tl/tcp
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/header.c
r6896409c r1812a0d 164 164 } 165 165 166 /** Create PDU with the specified header and text data. 167 * 168 * Note that you still need to set addresses in the returned PDU. 169 * 170 * @param hdr Header data 171 * @param hdr_size Header size in bytes 172 * @param text Text data 173 * @param text_size Text size in bytes 174 * @return New PDU 175 */ 176 tcp_pdu_t *tcp_pdu_create(void *hdr, size_t hdr_size, void *text, 177 size_t text_size) 178 { 179 tcp_pdu_t *pdu; 180 181 pdu = tcp_pdu_new(); 182 if (pdu == NULL) 183 return NULL; 184 185 pdu->header = malloc(hdr_size); 186 pdu->text = malloc(text_size); 187 if (pdu->header == NULL || pdu->text == NULL) 188 goto error; 189 190 memcpy(pdu->header, hdr, hdr_size); 191 memcpy(pdu->text, text, text_size); 192 193 pdu->header_size = hdr_size; 194 pdu->text_size = text_size; 195 196 return pdu; 197 198 error: 199 if (pdu->header != NULL) 200 free(pdu->header); 201 if (pdu->text != NULL) 202 free(pdu->text); 203 204 return NULL; 205 } 206 166 207 void tcp_pdu_delete(tcp_pdu_t *pdu) 167 208 { 209 free(pdu->header); 168 210 free(pdu->text); 169 211 free(pdu); -
uspace/srv/net/tl/tcp/header.h
r6896409c r1812a0d 36 36 #define HEADER_H 37 37 38 #include <sys/types.h> 38 39 #include "std.h" 39 40 #include "tcp_type.h" 40 41 42 extern tcp_pdu_t *tcp_pdu_create(void *, size_t, void *, size_t); 41 43 extern void tcp_pdu_delete(tcp_pdu_t *); 42 44 extern int tcp_pdu_decode(tcp_pdu_t *, tcp_sockpair_t *, tcp_segment_t **); 43 45 extern int tcp_pdu_encode(tcp_sockpair_t *, tcp_segment_t *, tcp_pdu_t **); 44 45 46 46 47 #endif -
uspace/srv/net/tl/tcp/tcp.c
r6896409c r1812a0d 36 36 37 37 #include <async.h> 38 #include <byteorder.h> 38 39 #include <errno.h> 39 40 #include <io/log.h> … … 41 42 #include <task.h> 42 43 44 #include <icmp_remote.h> 45 #include <ip_client.h> 46 #include <ip_interface.h> 47 #include <ipc/services.h> 48 #include <ipc/tl.h> 49 #include <tl_common.h> 50 #include <tl_skel.h> 51 #include <packet_client.h> 52 #include <packet_remote.h> 53 54 #include "header.h" 43 55 #include "ncsim.h" 44 56 #include "rqueue.h" 57 #include "std.h" 58 #include "tcp.h" 45 59 #include "test.h" 46 60 47 61 #define NAME "tcp" 62 63 static async_sess_t *net_sess; 64 static async_sess_t *icmp_sess; 65 static async_sess_t *ip_sess; 66 static packet_dimensions_t pkt_dims; 67 68 static void tcp_received_pdu(tcp_pdu_t *pdu); 69 70 /* Pull up packets into a single memory block. */ 71 static int pq_pullup(packet_t *packet, void **data, size_t *dsize) 72 { 73 packet_t *npacket; 74 size_t tot_len; 75 int length; 76 77 npacket = packet; 78 tot_len = 0; 79 do { 80 length = packet_get_data_length(packet); 81 if (length <= 0) 82 return EINVAL; 83 84 tot_len += length; 85 } while ((npacket = pq_next(npacket)) != NULL); 86 87 uint8_t *buf; 88 uint8_t *dp; 89 90 buf = calloc(tot_len, 1); 91 if (buf == NULL) { 92 free(buf); 93 return ENOMEM; 94 } 95 96 npacket = packet; 97 dp = buf; 98 do { 99 length = packet_get_data_length(packet); 100 if (length <= 0) { 101 free(buf); 102 return EINVAL; 103 } 104 105 memcpy(dp, packet_get_data(packet), length); 106 dp += length; 107 } while ((npacket = pq_next(npacket)) != NULL); 108 109 *data = buf; 110 *dsize = tot_len; 111 return EOK; 112 } 113 114 /** Process packet received from network layer. */ 115 static int tcp_received_msg(device_id_t device_id, packet_t *packet, 116 services_t error) 117 { 118 int rc; 119 size_t offset; 120 int length; 121 struct sockaddr_in *src_addr; 122 struct sockaddr_in *dest_addr; 123 size_t addr_len; 124 125 log_msg(LVL_DEBUG, "tcp_received_msg()"); 126 127 switch (error) { 128 case SERVICE_NONE: 129 break; 130 case SERVICE_ICMP: 131 default: 132 log_msg(LVL_WARN, "Unsupported service number %u", 133 (unsigned)error); 134 pq_release_remote(net_sess, packet_get_id(packet)); 135 return ENOTSUP; 136 } 137 138 /* Process and trim off IP header */ 139 log_msg(LVL_DEBUG, "tcp_received_msg() - IP header"); 140 141 rc = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL); 142 if (rc < 0) { 143 log_msg(LVL_WARN, "ip_client_process_packet() failed"); 144 pq_release_remote(net_sess, packet_get_id(packet)); 145 return rc; 146 } 147 148 offset = (size_t)rc; 149 length = packet_get_data_length(packet); 150 151 if (length < 0 || (size_t)length < offset) { 152 log_msg(LVL_WARN, "length=%d, dropping.", length); 153 pq_release_remote(net_sess, packet_get_id(packet)); 154 return EINVAL; 155 } 156 157 addr_len = packet_get_addr(packet, (uint8_t **)&src_addr, 158 (uint8_t **)&dest_addr); 159 if (addr_len <= 0) { 160 log_msg(LVL_WARN, "Failed to get packet address."); 161 pq_release_remote(net_sess, packet_get_id(packet)); 162 return EINVAL; 163 } 164 165 if (addr_len != sizeof(struct sockaddr_in)) { 166 log_msg(LVL_WARN, "Unsupported address size %zu (!= %zu)", 167 addr_len, sizeof(struct sockaddr_in)); 168 pq_release_remote(net_sess, packet_get_id(packet)); 169 return EINVAL; 170 } 171 172 rc = packet_trim(packet, offset, 0); 173 if (rc != EOK) { 174 log_msg(LVL_WARN, "Failed to trim packet."); 175 pq_release_remote(net_sess, packet_get_id(packet)); 176 return rc; 177 } 178 179 /* Pull up packets into a single memory block, pdu_raw. */ 180 log_msg(LVL_DEBUG, "tcp_received_msg() - pull up"); 181 uint8_t *pdu_raw; 182 size_t pdu_raw_size = 0; 183 184 pq_pullup(packet, (void **)&pdu_raw, &pdu_raw_size); 185 186 /* Split into header and payload. */ 187 188 log_msg(LVL_DEBUG, "tcp_received_msg() - split header/payload"); 189 190 tcp_pdu_t *pdu; 191 size_t hdr_size; 192 193 /* XXX Header options */ 194 hdr_size = sizeof(tcp_header_t); 195 196 if (pdu_raw_size < hdr_size) { 197 log_msg(LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu", 198 pdu_raw_size, hdr_size); 199 pq_release_remote(net_sess, packet_get_id(packet)); 200 return EINVAL; 201 } 202 203 log_msg(LVL_DEBUG, "pdu_raw_size=%zu, hdr_size=%zu", 204 pdu_raw_size, hdr_size); 205 pdu = tcp_pdu_create(pdu_raw, hdr_size, pdu_raw + hdr_size, 206 pdu_raw_size - hdr_size); 207 if (pdu == NULL) { 208 log_msg(LVL_WARN, "Failed creating PDU. Dropped."); 209 return ENOMEM; 210 } 211 212 free(pdu_raw); 213 214 pdu->src_addr.ipv4 = uint32_t_be2host(src_addr->sin_addr.s_addr); 215 pdu->dest_addr.ipv4 = uint32_t_be2host(dest_addr->sin_addr.s_addr); 216 log_msg(LVL_DEBUG, "src: 0x%08x, dest: 0x%08x", 217 pdu->src_addr.ipv4, pdu->dest_addr.ipv4); 218 219 tcp_received_pdu(pdu); 220 tcp_pdu_delete(pdu); 221 222 return EOK; 223 } 224 225 /** Receive packets from network layer. */ 226 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg) 227 { 228 packet_t *packet; 229 int rc; 230 231 log_msg(LVL_DEBUG, "tcp_receiver()"); 232 233 while (true) { 234 switch (IPC_GET_IMETHOD(*icall)) { 235 case NET_TL_RECEIVED: 236 log_msg(LVL_DEBUG, "method = NET_TL_RECEIVED"); 237 rc = packet_translate_remote(net_sess, &packet, 238 IPC_GET_PACKET(*icall)); 239 if (rc != EOK) { 240 log_msg(LVL_DEBUG, "Error %d translating packet.", rc); 241 async_answer_0(iid, (sysarg_t)rc); 242 break; 243 } 244 rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet, 245 IPC_GET_ERROR(*icall)); 246 async_answer_0(iid, (sysarg_t)rc); 247 break; 248 default: 249 log_msg(LVL_DEBUG, "method = %u", 250 (unsigned)IPC_GET_IMETHOD(*icall)); 251 async_answer_0(iid, ENOTSUP); 252 break; 253 } 254 255 iid = async_get_call(icall); 256 } 257 } 258 259 /** Transmit PDU over network layer. */ 260 void tcp_transmit_pdu(tcp_pdu_t *pdu) 261 { 262 struct sockaddr_in dest; 263 device_id_t dev_id; 264 void *phdr; 265 size_t phdr_len; 266 packet_dimension_t *pkt_dim; 267 int rc; 268 packet_t *packet; 269 void *pkt_data; 270 size_t pdu_size; 271 272 dest.sin_family = AF_INET; 273 dest.sin_port = 0; /* not needed */ 274 dest.sin_addr.s_addr = host2uint32_t_be(pdu->dest_addr.ipv4); 275 276 /* Find route. Obtained pseudo-header is not used. */ 277 rc = ip_get_route_req(ip_sess, IPPROTO_TCP, (struct sockaddr *)&dest, 278 sizeof(dest), &dev_id, &phdr, &phdr_len); 279 if (rc != EOK) { 280 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to find route."); 281 return; 282 } 283 284 rc = tl_get_ip_packet_dimension(ip_sess, &pkt_dims, dev_id, &pkt_dim); 285 if (rc != EOK) { 286 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to get dimension."); 287 return; 288 } 289 290 pdu_size = pdu->header_size + pdu->text_size; 291 292 packet = packet_get_4_remote(net_sess, pdu_size, pkt_dim->addr_len, 293 pkt_dim->prefix, pkt_dim->suffix); 294 if (!packet) { 295 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to get packet."); 296 return; 297 } 298 299 pkt_data = packet_suffix(packet, pdu_size); 300 if (!pkt_data) { 301 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to get pkt_data ptr."); 302 pq_release_remote(net_sess, packet_get_id(packet)); 303 return; 304 } 305 306 rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0); 307 if (rc != EOK) { 308 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to prepare IP packet part."); 309 pq_release_remote(net_sess, packet_get_id(packet)); 310 return; 311 } 312 313 rc = packet_set_addr(packet, NULL, (uint8_t *)&dest, sizeof(dest)); 314 if (rc != EOK) { 315 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to set packet address."); 316 pq_release_remote(net_sess, packet_get_id(packet)); 317 return; 318 } 319 320 /* Copy PDU data to packet */ 321 memcpy(pkt_data, pdu->header, pdu->header_size); 322 memcpy((uint8_t *)pkt_data + pdu->header_size, pdu->text, 323 pdu->text_size); 324 325 /* Transmit packet. XXX Transfers packet ownership to IP? */ 326 ip_send_msg(ip_sess, dev_id, packet, SERVICE_TCP, 0); 327 } 328 329 /** Process received PDU. */ 330 static void tcp_received_pdu(tcp_pdu_t *pdu) 331 { 332 tcp_segment_t *dseg; 333 tcp_sockpair_t rident; 334 335 log_msg(LVL_DEBUG, "tcp_received_pdu()"); 336 337 if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) { 338 log_msg(LVL_WARN, "Not enough memory. PDU dropped."); 339 return; 340 } 341 342 /* Insert decoded segment into rqueue */ 343 tcp_rqueue_insert_seg(&rident, dseg); 344 } 345 346 /* Called from libnet */ 347 void tl_connection(void) 348 { 349 log_msg(LVL_DEBUG, "tl_connection()"); 350 } 351 352 /* Called from libnet */ 353 int tl_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 354 size_t *answer_count) 355 { 356 log_msg(LVL_DEBUG, "tl_message()"); 357 return ENOTSUP; 358 } 359 360 /* Called from libnet */ 361 int tl_initialize(async_sess_t *sess) 362 { 363 int rc; 364 365 net_sess = sess; 366 icmp_sess = icmp_connect_module(); 367 368 log_msg(LVL_DEBUG, "tl_initialize()"); 369 370 ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_TCP, SERVICE_TCP, 371 tcp_receiver); 372 if (ip_sess == NULL) 373 return ENOENT; 374 375 rc = packet_dimensions_initialize(&pkt_dims); 376 if (rc != EOK) 377 return rc; 378 379 return EOK; 380 } 48 381 49 382 int main(int argc, char **argv) … … 59 392 } 60 393 61 printf(NAME ": Accepting connections\n");394 // printf(NAME ": Accepting connections\n"); 62 395 // task_retval(0); 63 396 … … 69 402 70 403 tcp_test(); 71 404 /* 72 405 async_manager(); 406 */ 407 tl_module_start(SERVICE_TCP); 73 408 74 409 /* Not reached */ -
uspace/srv/net/tl/tcp/test.c
r6896409c r1812a0d 103 103 tcp_uc_send(conn, (void *)msg, str_size(msg), 0); 104 104 105 async_usleep(1000*1000* 3/**20*2*/);105 async_usleep(1000*1000*20/**20*2*/); 106 106 printf("C: User close...\n"); 107 107 tcp_uc_close(conn); … … 115 115 116 116 printf("tcp_test()\n"); 117 118 async_usleep(1000*1000); 117 119 118 120 rc = thread_create(test_srv, NULL, "test_srv", &srv_tid); -
uspace/srv/net/tl/tcp/tqueue.c
r6896409c r1812a0d 50 50 #include "seq_no.h" 51 51 #include "tqueue.h" 52 #include "tcp.h" 52 53 #include "tcp_type.h" 53 54 … … 273 274 tcp_pdu_transmit(data, len); 274 275 */ 275 tcp_rqueue_bounce_seg(sp, seg);276 // tcp_rqueue_bounce_seg(sp, seg); 276 277 // tcp_ncsim_bounce_seg(sp, seg); 278 279 tcp_pdu_t *pdu; 280 281 if (tcp_pdu_encode(sp, seg, &pdu) != EOK) { 282 log_msg(LVL_WARN, "Not enough memory. Segment dropped."); 283 return; 284 } 285 286 tcp_transmit_pdu(pdu); 287 tcp_pdu_delete(pdu); 277 288 } 278 289
Note:
See TracChangeset
for help on using the changeset viewer.