Revision 5fafdf24 slirp/socket.c

b/slirp/socket.c
1 1
/*
2 2
 * Copyright (c) 1995 Danny Gasparovski.
3
 * 
4
 * Please read the file COPYRIGHT for the 
3
 *
4
 * Please read the file COPYRIGHT for the
5 5
 * terms and conditions of the copyright.
6 6
 */
7 7

  
......
29 29
	u_int fport;
30 30
{
31 31
	struct socket *so;
32
	
32

  
33 33
	for (so = head->so_next; so != head; so = so->so_next) {
34
		if (so->so_lport == lport && 
34
		if (so->so_lport == lport &&
35 35
		    so->so_laddr.s_addr == laddr.s_addr &&
36 36
		    so->so_faddr.s_addr == faddr.s_addr &&
37 37
		    so->so_fport == fport)
38 38
		   break;
39 39
	}
40
	
40

  
41 41
	if (so == head)
42 42
	   return (struct socket *)NULL;
43 43
	return so;
44
	
44

  
45 45
}
46 46

  
47 47
/*
......
53 53
socreate()
54 54
{
55 55
  struct socket *so;
56
	
56

  
57 57
  so = (struct socket *)malloc(sizeof(struct socket));
58 58
  if(so) {
59 59
    memset(so, 0, sizeof(struct socket));
......
78 78
    tcp_last_so = &tcb;
79 79
  else if (so == udp_last_so)
80 80
    udp_last_so = &udb;
81
	
81

  
82 82
  m_free(so->so_m);
83
	
84
  if(so->so_next && so->so_prev) 
83

  
84
  if(so->so_next && so->so_prev)
85 85
    remque(so);  /* crashes if so is not in a queue */
86 86

  
87 87
  free(so);
......
101 101
	int len = sb->sb_datalen - sb->sb_cc;
102 102
	struct iovec iov[2];
103 103
	int mss = so->so_tcpcb->t_maxseg;
104
	
104

  
105 105
	DEBUG_CALL("soread");
106 106
	DEBUG_ARG("so = %lx", (long )so);
107
	
108
	/* 
107

  
108
	/*
109 109
	 * No need to check if there's enough room to read.
110 110
	 * soread wouldn't have been called if there weren't
111 111
	 */
112
	
112

  
113 113
	len = sb->sb_datalen - sb->sb_cc;
114
	
114

  
115 115
	iov[0].iov_base = sb->sb_wptr;
116 116
	if (sb->sb_wptr < sb->sb_rptr) {
117 117
		iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
......
150 150
			n = 1;
151 151
		}
152 152
	}
153
	
153

  
154 154
#ifdef HAVE_READV
155 155
	nn = readv(so->s, (struct iovec *)iov, n);
156 156
	DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
157 157
#else
158 158
	nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
159
#endif	
159
#endif
160 160
	if (nn <= 0) {
161 161
		if (nn < 0 && (errno == EINTR || errno == EAGAIN))
162 162
			return 0;
......
167 167
			return -1;
168 168
		}
169 169
	}
170
	
170

  
171 171
#ifndef HAVE_READV
172 172
	/*
173 173
	 * If there was no error, try and read the second time round
......
184 184
            if (ret > 0)
185 185
                nn += ret;
186 186
        }
187
	
187

  
188 188
	DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
189 189
#endif
190
	
190

  
191 191
	/* Update fields */
192 192
	sb->sb_cc += nn;
193 193
	sb->sb_wptr += nn;
......
195 195
		sb->sb_wptr -= sb->sb_datalen;
196 196
	return nn;
197 197
}
198
	
198

  
199 199
/*
200 200
 * Get urgent data
201
 * 
201
 *
202 202
 * When the socket is created, we set it SO_OOBINLINE,
203 203
 * so when OOB data arrives, we soread() it and everything
204 204
 * in the send buffer is sent as urgent data
......
211 211

  
212 212
	DEBUG_CALL("sorecvoob");
213 213
	DEBUG_ARG("so = %lx", (long)so);
214
	
214

  
215 215
	/*
216 216
	 * We take a guess at how much urgent data has arrived.
217 217
	 * In most situations, when urgent data arrives, the next
218 218
	 * read() should get all the urgent data.  This guess will
219 219
	 * be wrong however if more data arrives just after the
220
	 * urgent data, or the read() doesn't return all the 
220
	 * urgent data, or the read() doesn't return all the
221 221
	 * urgent data.
222 222
	 */
223 223
	soread(so);
......
237 237
{
238 238
	struct sbuf *sb = &so->so_rcv;
239 239
	char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
240
	
240

  
241 241
	int n, len;
242
	
242

  
243 243
	DEBUG_CALL("sosendoob");
244 244
	DEBUG_ARG("so = %lx", (long)so);
245 245
	DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
246
	
246

  
247 247
	if (so->so_urgc > 2048)
248 248
	   so->so_urgc = 2048; /* XXXX */
249
	
249

  
250 250
	if (sb->sb_rptr < sb->sb_wptr) {
251 251
		/* We can send it directly */
252 252
		n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
253 253
		so->so_urgc -= n;
254
		
254
	
255 255
		DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
256 256
	} else {
257
		/* 
257
		/*
258 258
		 * Since there's no sendv or sendtov like writev,
259 259
		 * we must copy all data to a linear buffer then
260 260
		 * send it all
......
274 274
#ifdef DEBUG
275 275
		if (n != len)
276 276
		   DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
277
#endif		
277
#endif	
278 278
		DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
279 279
	}
280
	
280

  
281 281
	sb->sb_cc -= n;
282 282
	sb->sb_rptr += n;
283 283
	if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
284 284
		sb->sb_rptr -= sb->sb_datalen;
285
	
285

  
286 286
	return n;
287 287
}
288 288

  
289 289
/*
290
 * Write data from so_rcv to so's socket, 
290
 * Write data from so_rcv to so's socket,
291 291
 * updating all sbuf field as necessary
292 292
 */
293 293
int
......
298 298
	struct sbuf *sb = &so->so_rcv;
299 299
	int len = sb->sb_cc;
300 300
	struct iovec iov[2];
301
	
301

  
302 302
	DEBUG_CALL("sowrite");
303 303
	DEBUG_ARG("so = %lx", (long)so);
304
	
304

  
305 305
	if (so->so_urgc) {
306 306
		sosendoob(so);
307 307
		if (sb->sb_cc == 0)
......
312 312
	 * No need to check if there's something to write,
313 313
	 * sowrite wouldn't have been called otherwise
314 314
	 */
315
	
315

  
316 316
        len = sb->sb_cc;
317
	
317

  
318 318
	iov[0].iov_base = sb->sb_rptr;
319 319
	if (sb->sb_rptr < sb->sb_wptr) {
320 320
		iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
......
337 337

  
338 338
#ifdef HAVE_READV
339 339
	nn = writev(so->s, (const struct iovec *)iov, n);
340
	
340

  
341 341
	DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
342 342
#else
343 343
	nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0);
......
345 345
	/* This should never happen, but people tell me it does *shrug* */
346 346
	if (nn < 0 && (errno == EAGAIN || errno == EINTR))
347 347
		return 0;
348
	
348

  
349 349
	if (nn <= 0) {
350 350
		DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
351 351
			so->so_state, errno));
......
353 353
		tcp_sockclosed(sototcpcb(so));
354 354
		return -1;
355 355
	}
356
	
356

  
357 357
#ifndef HAVE_READV
358 358
	if (n == 2 && nn == iov[0].iov_len) {
359 359
            int ret;
......
363 363
        }
364 364
        DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
365 365
#endif
366
	
366

  
367 367
	/* Update sbuf */
368 368
	sb->sb_cc -= nn;
369 369
	sb->sb_rptr += nn;
370 370
	if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
371 371
		sb->sb_rptr -= sb->sb_datalen;
372
	
372

  
373 373
	/*
374 374
	 * If in DRAIN mode, and there's no more data, set
375 375
	 * it CANTSENDMORE
376 376
	 */
377 377
	if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
378 378
		sofcantsendmore(so);
379
	
379

  
380 380
	return nn;
381 381
}
382 382

  
......
389 389
{
390 390
	struct sockaddr_in addr;
391 391
	int addrlen = sizeof(struct sockaddr_in);
392
	
392

  
393 393
	DEBUG_CALL("sorecvfrom");
394 394
	DEBUG_ARG("so = %lx", (long)so);
395
	
395

  
396 396
	if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
397 397
	  char buff[256];
398 398
	  int len;
399
		
400
	  len = recvfrom(so->s, buff, 256, 0, 
399
	
400
	  len = recvfrom(so->s, buff, 256, 0,
401 401
			 (struct sockaddr *)&addr, &addrlen);
402 402
	  /* XXX Check if reply is "correct"? */
403
	  
403
	 
404 404
	  if(len == -1 || len == 0) {
405 405
	    u_char code=ICMP_UNREACH_PORT;
406 406

  
407 407
	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
408 408
	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
409
	    
409
	   
410 410
	    DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
411 411
			errno,strerror(errno)));
412 412
	    icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
......
422 422

  
423 423
	  if (!(m = m_get())) return;
424 424
	  m->m_data += if_maxlinkhdr;
425
		
426
	  /* 
425
	
426
	  /*
427 427
	   * XXX Shouldn't FIONREAD packets destined for port 53,
428 428
	   * but I don't know the max packet size for DNS lookups
429 429
	   */
430 430
	  len = M_FREEROOM(m);
431 431
	  /* if (so->so_fport != htons(53)) { */
432 432
	  ioctlsocket(so->s, FIONREAD, &n);
433
	  
433
	 
434 434
	  if (n > len) {
435 435
	    n = (m->m_data - m->m_dat) + m->m_len + n + 1;
436 436
	    m_inc(m, n);
437 437
	    len = M_FREEROOM(m);
438 438
	  }
439 439
	  /* } */
440
		
440
	
441 441
	  m->m_len = recvfrom(so->s, m->m_data, len, 0,
442 442
			      (struct sockaddr *)&addr, &addrlen);
443
	  DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", 
443
	  DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
444 444
		      m->m_len, errno,strerror(errno)));
445 445
	  if(m->m_len<0) {
446 446
	    u_char code=ICMP_UNREACH_PORT;
447 447

  
448 448
	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
449 449
	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
450
	    
450
	   
451 451
	    DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
452 452
	    icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
453 453
	    m_free(m);
......
470 470
	     *			m->m_len = 0;
471 471
	     *		}
472 472
	     */
473
	    
474
	    /* 
473
	   
474
	    /*
475 475
	     * If this packet was destined for CTL_ADDR,
476 476
	     * make it look like that's where it came from, done by udp_output
477 477
	     */
......
494 494
	DEBUG_CALL("sosendto");
495 495
	DEBUG_ARG("so = %lx", (long)so);
496 496
	DEBUG_ARG("m = %lx", (long)m);
497
	
497

  
498 498
        addr.sin_family = AF_INET;
499 499
	if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
500 500
	  /* It's an alias */
......
512 512
	addr.sin_port = so->so_fport;
513 513

  
514 514
	DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
515
	
515

  
516 516
	/* Don't care what port we get */
517 517
	ret = sendto(so->s, m->m_data, m->m_len, 0,
518 518
		     (struct sockaddr *)&addr, sizeof (struct sockaddr));
519 519
	if (ret < 0)
520 520
		return -1;
521
	
521

  
522 522
	/*
523 523
	 * Kill the socket if there's no reply in 4 minutes,
524 524
	 * but only if it's an expirable socket
......
548 548
	DEBUG_ARG("laddr = %x", laddr);
549 549
	DEBUG_ARG("lport = %d", lport);
550 550
	DEBUG_ARG("flags = %x", flags);
551
	
551

  
552 552
	if ((so = socreate()) == NULL) {
553 553
	  /* free(so);      Not sofree() ??? free(NULL) == NOP */
554 554
	  return NULL;
555 555
	}
556
	
556

  
557 557
	/* Don't tcp_attach... we don't need so_snd nor so_rcv */
558 558
	if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
559 559
		free(so);
560 560
		return NULL;
561 561
	}
562 562
	insque(so,&tcb);
563
	
564
	/* 
563

  
564
	/*
565 565
	 * SS_FACCEPTONCE sockets must time out.
566 566
	 */
567 567
	if (flags & SS_FACCEPTONCE)
568 568
	   so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
569
	
569

  
570 570
	so->so_state = (SS_FACCEPTCONN|flags);
571 571
	so->so_lport = lport; /* Kept in network format */
572 572
	so->so_laddr.s_addr = laddr; /* Ditto */
573
	
573

  
574 574
	addr.sin_family = AF_INET;
575 575
	addr.sin_addr.s_addr = INADDR_ANY;
576 576
	addr.sin_port = port;
577
	
577

  
578 578
	if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
579 579
	    (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
580 580
	    (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
581 581
	    (listen(s,1) < 0)) {
582 582
		int tmperrno = errno; /* Don't clobber the real reason we failed */
583
		
583
	
584 584
		close(s);
585 585
		sofree(so);
586 586
		/* Restore the real errno */
......
592 592
		return NULL;
593 593
	}
594 594
	setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
595
	
595

  
596 596
	getsockname(s,(struct sockaddr *)&addr,&addrlen);
597 597
	so->so_fport = addr.sin_port;
598 598
	if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
......
604 604
	return so;
605 605
}
606 606

  
607
/* 
607
/*
608 608
 * Data is available in so_rcv
609 609
 * Just write() the data to the socket
610 610
 * XXX not yet...
......
616 616
/*	sowrite(so); */
617 617
/*	FD_CLR(so->s,&writefds); */
618 618
}
619
	
619

  
620 620
/*
621 621
 * Data has been freed in so_snd
622 622
 * We have room for a read() if we want to

Also available in: Unified diff