Changeset c76e926 in mainline
- Timestamp:
- 2012-02-01T21:18:27Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ecff3d9
- Parents:
- c8916d15
- Files:
-
- 5 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile.common
rc8916d15 rc76e926 106 106 $(USPACE_PATH)/srv/fs/ext2fs/ext2fs \ 107 107 $(USPACE_PATH)/srv/hid/remcons/remcons \ 108 $(USPACE_PATH)/srv/inet/inet \ 108 109 $(USPACE_PATH)/srv/taskmon/taskmon \ 110 $(USPACE_PATH)/srv/tcp/tcp \ 109 111 $(USPACE_PATH)/srv/devman/devman 110 112 -
uspace/Makefile
rc8916d15 rc76e926 71 71 srv/loc \ 72 72 srv/devman \ 73 srv/inet \ 73 74 srv/loader \ 74 75 srv/ns \ 75 76 srv/taskmon \ 77 srv/tcp \ 76 78 srv/vfs \ 77 79 srv/bd/ata_bd \ -
uspace/lib/c/Makefile
rc8916d15 rc76e926 87 87 generic/task.c \ 88 88 generic/futex.c \ 89 generic/inet.c \ 89 90 generic/io/asprintf.c \ 90 91 generic/io/io.c \ -
uspace/lib/c/include/ipc/services.h
rc8916d15 rc76e926 52 52 } services_t; 53 53 54 #define SERVICE_NAME_INET "net/inet" 55 54 56 #endif 55 57 -
uspace/srv/tcp/Makefile
rc8916d15 rc76e926 27 27 # 28 28 29 USPACE_PREFIX = ../.. /../..29 USPACE_PREFIX = ../.. 30 30 LIBS = $(LIBNET_PREFIX)/libnet.a 31 31 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -
uspace/srv/tcp/sock.c
rc8916d15 rc76e926 38 38 #include <async.h> 39 39 #include <errno.h> 40 #include <inet/inet.h> 40 41 #include <io/log.h> 41 #include <ip _client.h>42 #include <ipc/services.h> 42 43 #include <ipc/socket.h> 43 44 #include <net/modules.h> 44 45 #include <net/socket.h> 46 #include <ns.h> 45 47 46 48 #include "sock.h" … … 63 65 static socket_ports_t gsock; 64 66 67 static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg); 65 68 static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg); 66 69 67 void tcp_sock_init(void) 68 { 70 int tcp_sock_init(void) 71 { 72 int rc; 73 69 74 socket_ports_initialize(&gsock); 75 76 async_set_client_connection(tcp_sock_connection); 77 78 rc = service_register(SERVICE_TCP); 79 if (rc != EOK) 80 return EEXIST; 81 82 return EOK; 70 83 } 71 84 … … 273 286 tcp_sock_t lsocket; 274 287 tcp_sock_t fsocket; 275 nic_device_id_t dev_id;276 tcp_phdr_t *phdr;277 size_t phdr_len;278 288 279 289 log_msg(LVL_DEBUG, "tcp_sock_connect()"); … … 309 319 310 320 if (socket->laddr.ipv4 == TCP_IPV4_ANY) { 311 /* Find route to determine local IP address. */ 312 rc = ip_get_route_req(ip_sess, IPPROTO_TCP, 313 (struct sockaddr *)addr, sizeof(*addr), &dev_id, 314 (void **)&phdr, &phdr_len); 321 /* Determine local IP address */ 322 inet_addr_t loc_addr, rem_addr; 323 324 rem_addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr); 325 rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr); 315 326 if (rc != EOK) { 316 327 fibril_mutex_unlock(&socket->lock); 317 328 async_answer_0(callid, rc); 318 log_msg(LVL_DEBUG, "tcp_transmit_connect: Failed to find route."); 319 return; 320 } 321 322 socket->laddr.ipv4 = uint32_t_be2host(phdr->src_addr); 329 log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to " 330 "determine local address."); 331 return; 332 } 333 334 socket->laddr.ipv4 = loc_addr.ipv4; 323 335 log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4); 324 free(phdr);325 336 } 326 337 … … 713 724 } 714 725 715 rc = socket_destroy( net_sess, socket_id, &client->sockets, &gsock,726 rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock, 716 727 tcp_free_sock_data); 717 728 if (rc != EOK) { … … 764 775 } 765 776 766 int tcp_sock_connection(async_sess_t *sess, ipc_callid_t iid, ipc_call_t icall)777 static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 767 778 { 768 779 ipc_callid_t callid; … … 773 784 async_answer_0(iid, EOK); 774 785 775 client.sess = sess;786 client.sess = async_callback_receive(EXCHANGE_SERIALIZE); 776 787 socket_cores_initialize(&client.sockets); 777 788 … … 824 835 } 825 836 } 826 827 return EOK;828 837 } 829 838 -
uspace/srv/tcp/sock.h
rc8916d15 rc76e926 38 38 #include <async.h> 39 39 40 extern void tcp_sock_init(void); 41 extern int tcp_sock_connection(async_sess_t *, ipc_callid_t, ipc_call_t); 40 extern int tcp_sock_init(void); 42 41 43 42 #endif -
uspace/srv/tcp/tcp.c
rc8916d15 rc76e926 1 1 /* 2 * Copyright (c) 201 1Jiri Svoboda2 * Copyright (c) 2012 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 39 39 #include <byteorder.h> 40 40 #include <errno.h> 41 #include <inet/inet.h> 41 42 #include <io/log.h> 42 43 #include <stdio.h> 43 44 #include <task.h> 44 45 #include <icmp_remote.h>46 #include <ip_client.h>47 #include <ip_interface.h>48 #include <ipc/services.h>49 #include <ipc/tl.h>50 #include <tl_common.h>51 #include <tl_skel.h>52 #include <packet_client.h>53 #include <packet_remote.h>54 45 55 46 #include "ncsim.h" … … 63 54 #define NAME "tcp" 64 55 65 async_sess_t *net_sess; 66 static async_sess_t *icmp_sess; 67 async_sess_t *ip_sess; 68 packet_dimensions_t pkt_dims; 69 56 static int tcp_inet_ev_recv(inet_dgram_t *dgram); 70 57 static void tcp_received_pdu(tcp_pdu_t *pdu); 71 58 72 /* Pull up packets into a single memory block. */ 73 static int pq_pullup(packet_t *packet, void **data, size_t *dsize) 74 { 75 packet_t *npacket; 76 size_t tot_len; 77 int length; 78 79 npacket = packet; 80 tot_len = 0; 81 do { 82 length = packet_get_data_length(packet); 83 if (length <= 0) 84 return EINVAL; 85 86 tot_len += length; 87 } while ((npacket = pq_next(npacket)) != NULL); 88 89 uint8_t *buf; 90 uint8_t *dp; 91 92 buf = calloc(tot_len, 1); 93 if (buf == NULL) { 94 free(buf); 95 return ENOMEM; 96 } 97 98 npacket = packet; 99 dp = buf; 100 do { 101 length = packet_get_data_length(packet); 102 if (length <= 0) { 103 free(buf); 104 return EINVAL; 105 } 106 107 memcpy(dp, packet_get_data(packet), length); 108 dp += length; 109 } while ((npacket = pq_next(npacket)) != NULL); 110 111 *data = buf; 112 *dsize = tot_len; 113 return EOK; 114 } 115 116 /** Process packet received from network layer. */ 117 static int tcp_received_msg(nic_device_id_t device_id, packet_t *packet, 118 services_t error) 119 { 120 int rc; 121 size_t offset; 122 int length; 123 struct sockaddr_in *src_addr; 124 struct sockaddr_in *dest_addr; 125 size_t addr_len; 126 127 log_msg(LVL_DEBUG, "tcp_received_msg()"); 128 129 switch (error) { 130 case SERVICE_NONE: 131 break; 132 case SERVICE_ICMP: 133 default: 134 log_msg(LVL_WARN, "Unsupported service number %u", 135 (unsigned)error); 136 pq_release_remote(net_sess, packet_get_id(packet)); 137 return ENOTSUP; 138 } 139 140 /* Process and trim off IP header */ 141 log_msg(LVL_DEBUG, "tcp_received_msg() - IP header"); 142 143 rc = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL); 144 if (rc < 0) { 145 log_msg(LVL_WARN, "ip_client_process_packet() failed"); 146 pq_release_remote(net_sess, packet_get_id(packet)); 147 return rc; 148 } 149 150 offset = (size_t)rc; 151 length = packet_get_data_length(packet); 152 153 if (length < 0 || (size_t)length < offset) { 154 log_msg(LVL_WARN, "length=%d, dropping.", length); 155 pq_release_remote(net_sess, packet_get_id(packet)); 156 return EINVAL; 157 } 158 159 addr_len = packet_get_addr(packet, (uint8_t **)&src_addr, 160 (uint8_t **)&dest_addr); 161 if (addr_len <= 0) { 162 log_msg(LVL_WARN, "Failed to get packet address."); 163 pq_release_remote(net_sess, packet_get_id(packet)); 164 return EINVAL; 165 } 166 167 if (addr_len != sizeof(struct sockaddr_in)) { 168 log_msg(LVL_WARN, "Unsupported address size %zu (!= %zu)", 169 addr_len, sizeof(struct sockaddr_in)); 170 pq_release_remote(net_sess, packet_get_id(packet)); 171 return EINVAL; 172 } 173 174 rc = packet_trim(packet, offset, 0); 175 if (rc != EOK) { 176 log_msg(LVL_WARN, "Failed to trim packet."); 177 pq_release_remote(net_sess, packet_get_id(packet)); 178 return rc; 179 } 180 181 /* Pull up packets into a single memory block, pdu_raw. */ 182 log_msg(LVL_DEBUG, "tcp_received_msg() - pull up"); 59 static inet_ev_ops_t tcp_inet_ev_ops = { 60 .recv = tcp_inet_ev_recv 61 }; 62 63 /** Received datagram callback */ 64 static int tcp_inet_ev_recv(inet_dgram_t *dgram) 65 { 183 66 uint8_t *pdu_raw; 184 size_t pdu_raw_size = 0; 185 186 pq_pullup(packet, (void **)&pdu_raw, &pdu_raw_size); 67 size_t pdu_raw_size; 68 69 log_msg(LVL_DEBUG, "tcp_inet_ev_recv()"); 70 71 pdu_raw = dgram->data; 72 pdu_raw_size = dgram->size; 187 73 188 74 /* Split into header and payload. */ 189 75 190 log_msg(LVL_DEBUG, "tcp_ received_msg() - split header/payload");76 log_msg(LVL_DEBUG, "tcp_inet_ev_recv() - split header/payload"); 191 77 192 78 tcp_pdu_t *pdu; … … 198 84 log_msg(LVL_WARN, "pdu_raw_size = %zu < sizeof(tcp_header_t) = %zu", 199 85 pdu_raw_size, sizeof(tcp_header_t)); 200 pq_release_remote(net_sess, packet_get_id(packet));201 86 return EINVAL; 202 87 } … … 211 96 log_msg(LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu", 212 97 pdu_raw_size, hdr_size); 213 pq_release_remote(net_sess, packet_get_id(packet));214 98 return EINVAL; 215 99 } … … 217 101 if (hdr_size < sizeof(tcp_header_t)) { 218 102 log_msg(LVL_WARN, "hdr_size = %zu < sizeof(tcp_header_t) = %zu", 219 hdr_size, sizeof(tcp_header_t)); 220 pq_release_remote(net_sess, packet_get_id(packet)); 221 return EINVAL; 103 hdr_size, sizeof(tcp_header_t)); return EINVAL; 222 104 } 223 105 … … 231 113 } 232 114 233 free(pdu_raw); 234 235 pdu->src_addr.ipv4 = uint32_t_be2host(src_addr->sin_addr.s_addr); 236 pdu->dest_addr.ipv4 = uint32_t_be2host(dest_addr->sin_addr.s_addr); 115 pdu->src_addr.ipv4 = dgram->src.ipv4; 116 pdu->dest_addr.ipv4 = dgram->dest.ipv4; 237 117 log_msg(LVL_DEBUG, "src: 0x%08x, dest: 0x%08x", 238 118 pdu->src_addr.ipv4, pdu->dest_addr.ipv4); … … 244 124 } 245 125 246 /** Receive packets from network layer. */247 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)248 {249 packet_t *packet;250 int rc;251 252 log_msg(LVL_DEBUG, "tcp_receiver()");253 254 while (true) {255 switch (IPC_GET_IMETHOD(*icall)) {256 case NET_TL_RECEIVED:257 log_msg(LVL_DEBUG, "method = NET_TL_RECEIVED");258 rc = packet_translate_remote(net_sess, &packet,259 IPC_GET_PACKET(*icall));260 if (rc != EOK) {261 log_msg(LVL_DEBUG, "Error %d translating packet.", rc);262 async_answer_0(iid, (sysarg_t)rc);263 break;264 }265 rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet,266 IPC_GET_ERROR(*icall));267 async_answer_0(iid, (sysarg_t)rc);268 break;269 default:270 log_msg(LVL_DEBUG, "method = %u",271 (unsigned)IPC_GET_IMETHOD(*icall));272 async_answer_0(iid, ENOTSUP);273 break;274 }275 276 iid = async_get_call(icall);277 }278 }279 280 126 /** Transmit PDU over network layer. */ 281 127 void tcp_transmit_pdu(tcp_pdu_t *pdu) 282 128 { 283 struct sockaddr_in dest;284 nic_device_id_t dev_id;285 void *phdr;286 size_t phdr_len;287 packet_dimension_t *pkt_dim;288 129 int rc; 289 packet_t *packet; 290 void *pkt_data; 291 size_t pdu_size; 292 293 dest.sin_family = AF_INET; 294 dest.sin_port = 0; /* not needed */ 295 dest.sin_addr.s_addr = host2uint32_t_be(pdu->dest_addr.ipv4); 296 297 /* Find route. Obtained pseudo-header is not used. */ 298 rc = ip_get_route_req(ip_sess, IPPROTO_TCP, (struct sockaddr *)&dest, 299 sizeof(dest), &dev_id, &phdr, &phdr_len); 300 if (rc != EOK) { 301 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to find route."); 130 uint8_t *pdu_raw; 131 size_t pdu_raw_size; 132 inet_dgram_t dgram; 133 134 pdu_raw_size = pdu->header_size + pdu->text_size; 135 pdu_raw = malloc(pdu_raw_size); 136 if (pdu_raw == NULL) { 137 log_msg(LVL_ERROR, "Failed to transmit PDU. Out of memory."); 302 138 return; 303 139 } 304 140 305 rc = tl_get_ip_packet_dimension(ip_sess, &pkt_dims, dev_id, &pkt_dim); 306 if (rc != EOK) { 307 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to get dimension."); 308 return; 309 } 310 311 pdu_size = pdu->header_size + pdu->text_size; 312 313 packet = packet_get_4_remote(net_sess, pdu_size, pkt_dim->addr_len, 314 pkt_dim->prefix, pkt_dim->suffix); 315 if (!packet) { 316 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to get packet."); 317 return; 318 } 319 320 pkt_data = packet_suffix(packet, pdu_size); 321 if (!pkt_data) { 322 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to get pkt_data ptr."); 323 pq_release_remote(net_sess, packet_get_id(packet)); 324 return; 325 } 326 327 rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0); 328 if (rc != EOK) { 329 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to prepare IP packet part."); 330 pq_release_remote(net_sess, packet_get_id(packet)); 331 return; 332 } 333 334 rc = packet_set_addr(packet, NULL, (uint8_t *)&dest, sizeof(dest)); 335 if (rc != EOK) { 336 log_msg(LVL_DEBUG, "tcp_transmit_pdu: Failed to set packet address."); 337 pq_release_remote(net_sess, packet_get_id(packet)); 338 return; 339 } 340 341 /* Copy PDU data to packet */ 342 memcpy(pkt_data, pdu->header, pdu->header_size); 343 memcpy((uint8_t *)pkt_data + pdu->header_size, pdu->text, 141 memcpy(pdu_raw, pdu->header, pdu->header_size); 142 memcpy(pdu_raw + pdu->header_size, pdu->text, 344 143 pdu->text_size); 345 144 346 /* Transmit packet. XXX Transfers packet ownership to IP? */ 347 ip_send_msg(ip_sess, dev_id, packet, SERVICE_TCP, 0); 145 dgram.src.ipv4 = pdu->src_addr.ipv4; 146 dgram.dest.ipv4 = pdu->dest_addr.ipv4; 147 dgram.tos = 0; 148 dgram.data = pdu_raw; 149 dgram.size = pdu_raw_size; 150 151 rc = inet_send(&dgram, INET_TTL_MAX, 0); 152 if (rc != EOK) 153 log_msg(LVL_ERROR, "Failed to transmit PDU."); 348 154 } 349 155 … … 365 171 } 366 172 367 /* Called from libnet */ 368 void tl_connection(void) 369 { 370 log_msg(LVL_DEBUG, "tl_connection()"); 371 } 372 373 /* Called from libnet */ 374 int tl_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 375 size_t *answer_count) 376 { 377 async_sess_t *callback; 378 379 log_msg(LVL_DEBUG, "tl_message()"); 380 381 *answer_count = 0; 382 callback = async_callback_receive_start(EXCHANGE_SERIALIZE, call); 383 if (callback) 384 return tcp_sock_connection(callback, callid, *call); 385 386 return ENOTSUP; 387 } 388 389 /* Called from libnet */ 390 int tl_initialize(async_sess_t *sess) 173 static int tcp_init(void) 391 174 { 392 175 int rc; 393 176 394 net_sess = sess; 395 icmp_sess = icmp_connect_module(); 396 397 log_msg(LVL_DEBUG, "tl_initialize()"); 398 399 tcp_sock_init(); 400 401 ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_TCP, SERVICE_TCP, 402 tcp_receiver); 403 if (ip_sess == NULL) 177 log_msg(LVL_DEBUG, "tcp_init()"); 178 179 tcp_rqueue_init(); 180 tcp_rqueue_thread_start(); 181 182 tcp_ncsim_init(); 183 tcp_ncsim_thread_start(); 184 185 if (0) tcp_test(); 186 187 rc = inet_init(42, &tcp_inet_ev_ops); 188 if (rc != EOK) 404 189 return ENOENT; 405 190 406 rc = packet_dimensions_initialize(&pkt_dims);191 rc = tcp_sock_init(); 407 192 if (rc != EOK) 408 return rc;193 return ENOENT; 409 194 410 195 return EOK; … … 423 208 } 424 209 425 // printf(NAME ": Accepting connections\n"); 426 // task_retval(0); 427 428 tcp_rqueue_init(); 429 tcp_rqueue_thread_start(); 430 431 tcp_ncsim_init(); 432 tcp_ncsim_thread_start(); 433 434 if (0) tcp_test(); 435 /* 210 tcp_init(); 211 task_retval(0); 436 212 async_manager(); 437 */438 tl_module_start(SERVICE_TCP);439 213 440 214 /* Not reached */ -
uspace/srv/tcp/tcp.h
rc8916d15 rc76e926 37 37 38 38 #include <async.h> 39 #include <packet_remote.h>40 39 #include "tcp_type.h" 41 40 42 extern async_sess_t *net_sess;43 extern async_sess_t *ip_sess;44 41 extern void tcp_transmit_pdu(tcp_pdu_t *); 45 42
Note:
See TracChangeset
for help on using the changeset viewer.