loopbackmedium.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. #include "ip.h"
  8. enum
  9. {
  10. Maxtu= 16*1024,
  11. };
  12. typedef struct LB LB;
  13. struct LB
  14. {
  15. Proc *readp;
  16. Queue *q;
  17. Fs *f;
  18. };
  19. static void loopbackread(void *a);
  20. static void
  21. loopbackbind(Ipifc *ifc, int, char**)
  22. {
  23. LB *lb;
  24. lb = smalloc(sizeof(*lb));
  25. lb->f = ifc->conv->p->f;
  26. lb->q = qopen(1024*1024, Qmsg, nil, nil);
  27. ifc->arg = lb;
  28. ifc->mbps = 1000;
  29. kproc("loopbackread", loopbackread, ifc);
  30. }
  31. static void
  32. loopbackunbind(Ipifc *ifc)
  33. {
  34. LB *lb = ifc->arg;
  35. if(lb->readp)
  36. postnote(lb->readp, 1, "unbind", 0);
  37. /* wait for reader to die */
  38. while(lb->readp != 0)
  39. tsleep(&up->sleep, return0, 0, 300);
  40. /* clean up */
  41. qfree(lb->q);
  42. free(lb);
  43. }
  44. static void
  45. loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*)
  46. {
  47. LB *lb;
  48. lb = ifc->arg;
  49. if(qpass(lb->q, bp) < 0)
  50. ifc->outerr++;
  51. ifc->out++;
  52. }
  53. static void
  54. loopbackread(void *a)
  55. {
  56. Ipifc *ifc;
  57. Block *bp;
  58. LB *lb;
  59. ifc = a;
  60. lb = ifc->arg;
  61. lb->readp = up; /* hide identity under a rock for unbind */
  62. if(waserror()){
  63. lb->readp = 0;
  64. pexit("hangup", 1);
  65. }
  66. for(;;){
  67. bp = qbread(lb->q, Maxtu);
  68. if(bp == nil)
  69. continue;
  70. ifc->in++;
  71. if(!canrlock(ifc)){
  72. freeb(bp);
  73. continue;
  74. }
  75. if(waserror()){
  76. runlock(ifc);
  77. nexterror();
  78. }
  79. if(ifc->lifc == nil)
  80. freeb(bp);
  81. else
  82. ipiput4(lb->f, ifc, bp);
  83. runlock(ifc);
  84. poperror();
  85. }
  86. }
  87. Medium loopbackmedium =
  88. {
  89. .hsize= 0,
  90. .mintu= 0,
  91. .maxtu= Maxtu,
  92. .maclen= 0,
  93. .name= "loopback",
  94. .bind= loopbackbind,
  95. .unbind= loopbackunbind,
  96. .bwrite= loopbackbwrite,
  97. };
  98. void
  99. loopbackmediumlink(void)
  100. {
  101. addipmedium(&loopbackmedium);
  102. }