Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Extensive, Pedantic Error Checking in Linux module, especially for memory
[palacios.git] / linux_module / iface-keyed-stream.c
1 /*
2  * Palacios keyed stream interface
3  *
4  * Plus implementations for mem, file, and user space implementations
5  *
6  * (c) Peter Dinda, 2011 (interface, mem + file implementations + recooked user impl)
7  * (c) Clint Sbisa, 2011 (initial user space implementation on which this is based)
8  * (c) Diana Palsetia & Steve Rangel, 2012 (network based implementation)       
9  */
10
11 #include <linux/fs.h>
12 #include <linux/file.h>
13 #include <linux/uaccess.h>
14 #include <linux/namei.h>
15 #include <linux/vmalloc.h>
16 #include <linux/poll.h>
17 #include <linux/anon_inodes.h>
18
19 #include "palacios.h"
20 #include "util-hashtable.h"
21 #include "linux-exts.h"
22 #include "vm.h"
23
24 #define sint64_t int64_t
25 #include <interfaces/vmm_keyed_stream.h>
26
27 #include "iface-keyed-stream-user.h"
28
29 #include <interfaces/vmm_socket.h>
30
31 #include <linux/spinlock.h>
32 #include <asm/uaccess.h>
33 #include <linux/inet.h>
34 #include <linux/kthread.h>
35 #include <linux/netdevice.h>
36 #include <linux/ip.h>
37 #include <linux/in.h>
38 #include <linux/string.h>
39 #include <linux/preempt.h>
40 #include <linux/sched.h>
41 #include <linux/list.h>
42 #include <linux/syscalls.h>
43
44 #include <linux/module.h>
45 #include <linux/kernel.h>
46 #include <linux/socket.h>
47 #include <linux/net.h>
48 #include <linux/slab.h>
49
50
51 /*
52   This is an implementation of the Palacios keyed stream interface
53   that supports four flavors of streams:
54
55   "mem:"   Streams are stored in a hash table
56   The values for this hash table are hash tables associated with 
57   each stream.   
58
59   "file:"  Streams are stored in files.  Each high-level
60   open corresponds to a directory, while a key corresponds to
61   a distinct file in that directory. 
62
63   "net:"  Streams are carried over the network.  Each
64    high level open corresponds to a TCP connection, while
65    each key corresponds to a context on the stream.
66       "net:a:<ip>:<port>" => Bind to <ip>:<port> and accept a connection
67       "net:c:<ip>:<port>" => Connect to <ip>:<port>
68
69   "user:" Stream requests are bounced to user space to be 
70    handled there.  A rendezvous approach similar to the host 
71    device userland support is used
72    
73 */
74
75 #define STREAM_GENERIC 0
76 #define STREAM_MEM     1
77 #define STREAM_FILE    2
78 #define STREAM_USER    3
79 #define STREAM_NETWORK 4
80
81 /*
82   All keyed streams and streams indicate their implementation type within the first field
83  */
84 struct generic_keyed_stream {
85     int stype;
86 };
87
88 struct generic_stream {
89     int stype;
90 };
91   
92
93
94
95 /****************************************************************************************
96    Memory-based implementation  ("mem:")
97 ****************************************************************************************/
98
99 #define DEF_NUM_STREAMS 16
100 #define DEF_NUM_KEYS    128
101 #define DEF_SIZE        128
102
103 /*
104   A memory keyed stream is a pointer to the underlying hash table
105   while a memory stream contains an extensible buffer for the stream
106  */
107 struct mem_keyed_stream {
108     int stype;
109     v3_keyed_stream_open_t ot;
110     struct hashtable *ht;
111 };
112
113 struct mem_stream {
114     int       stype;
115     char     *data;
116     uint32_t  size;
117     uint32_t  data_max;
118     uint32_t  ptr;
119 };
120
121 static struct mem_stream *create_mem_stream_internal(uint64_t size)
122 {
123     struct mem_stream *m = palacios_alloc(sizeof(struct mem_stream));
124
125     if (!m) {
126         return 0;
127     }
128
129
130     m->data = vmalloc(size);
131     
132     if (!m->data) { 
133         palacios_free(m);
134         return 0;
135     }
136
137     m->stype = STREAM_MEM;
138     m->size=size;
139     m->ptr=0;
140     m->data_max=0;
141     
142     return m;
143 }
144
145
146 static struct mem_stream *create_mem_stream(void)
147 {
148     return create_mem_stream_internal(DEF_SIZE);
149 }
150
151 static void destroy_mem_stream(struct mem_stream *m)
152 {
153     if (m) {
154         if (m->data) {
155             vfree(m->data);
156         }
157         m->data=0;
158         palacios_free(m);
159     }
160 }
161     
162 static int expand_mem_stream(struct mem_stream *m, uint32_t new_size)
163 {
164     void *data = vmalloc(new_size);
165     uint32_t nc;
166
167     if (!data) { 
168         return -1;
169     }
170     
171     nc = (new_size<m->data_max) ? new_size : m->data_max;
172
173     memcpy(data,m->data,nc);
174
175     vfree(m->data);
176
177     m->data=data;
178     m->size=new_size;
179     if (m->size<m->data_max) { 
180         m->data_max=m->size;
181     }
182    
183     return 0;
184 }
185
186 static uint32_t write_mem_stream(struct mem_stream *m,
187                                  void *data,
188                                  uint32_t len)
189 {
190     if ((m->ptr + len) > m->size) { 
191         if (expand_mem_stream(m,m->ptr + len)) { 
192             return 0;
193         }
194     }
195     memcpy(m->data+m->ptr,data,len);
196     m->ptr+=len;
197     m->data_max=m->ptr;
198     
199     return len;
200
201 }
202
203 static uint32_t read_mem_stream(struct mem_stream *m,
204                                 void *data,
205                                 uint32_t len)
206 {
207     if ((m->ptr + len) > m->data_max) { 
208         return 0;
209     }
210     memcpy(data,m->data+m->ptr,len);
211     m->ptr+=len;
212     
213     return len;
214
215 }
216
217
218 static void reset_mem_stream(struct mem_stream *m)
219 {
220     m->ptr=0;
221 }
222
223
224 static inline uint_t hash_func(addr_t key)
225 {
226     return palacios_hash_buffer((uchar_t*)key,strlen((uchar_t*)key));
227 }
228
229 static inline int hash_comp(addr_t k1, addr_t k2)
230 {
231     return strcasecmp((char*)k1,(char*)k2)==0;
232 }
233
234
235 // This stores all the memory keyed streams streams
236 static struct hashtable *mem_streams=0;
237
238
239 static v3_keyed_stream_t open_stream_mem(char *url,
240                                          v3_keyed_stream_open_t ot)
241 {
242
243     if (strncasecmp(url,"mem:",4)) { 
244         WARNING("illegitimate attempt to open memory stream \"%s\"\n",url);
245         return 0;
246     }
247
248     switch (ot) { 
249         case V3_KS_RD_ONLY:
250         case V3_KS_WR_ONLY: {
251             struct mem_keyed_stream *mks = (struct mem_keyed_stream *) palacios_htable_search(mem_streams,(addr_t)(url+4));
252             if (mks) { 
253                 mks->ot=ot;
254             }
255             return (v3_keyed_stream_t) mks;
256         }
257             break;
258
259         case V3_KS_WR_ONLY_CREATE: {
260             struct mem_keyed_stream *mks = (struct mem_keyed_stream *) palacios_htable_search(mem_streams,(addr_t)(url+4));
261             if (!mks) { 
262                 char *mykey;
263
264                 mykey = palacios_alloc(strlen(url+4)+1);
265
266                 if (!mykey) { 
267                     ERROR("cannot allocate space for new in-memory keyed stream %s\n",url);
268                     return 0;
269                 }
270
271                 strcpy(mykey,url+4);
272                 
273                 mks = (struct mem_keyed_stream *) palacios_alloc(sizeof(struct mem_keyed_stream));
274
275                 if (!mks) { 
276                     palacios_free(mykey);
277                     ERROR("cannot allocate in-memory keyed stream %s\n",url);
278                     return 0;
279                 }
280             
281                 mks->ht = (void*) palacios_create_htable(DEF_NUM_KEYS,hash_func,hash_comp);
282                 if (!mks->ht) { 
283                     palacios_free(mks);
284                     palacios_free(mykey);
285                     ERROR("cannot allocate in-memory keyed stream %s\n",url);
286                     return 0;
287                 }
288
289                 
290                 if (!palacios_htable_insert(mem_streams,(addr_t)(mykey),(addr_t)mks)) { 
291                     palacios_free_htable(mks->ht,1,1);
292                     palacios_free(mks);
293                     palacios_free(mykey);
294                     ERROR("cannot insert in-memory keyed stream %s\n",url);
295                     return 0;
296                 }
297                 mks->stype=STREAM_MEM;
298             }
299
300             mks->ot=V3_KS_WR_ONLY;
301             
302             return mks;
303             
304         }
305             break;
306
307         default:
308             ERROR("unsupported open type in open_stream_mem\n");
309             break;
310     }
311     
312     return 0;
313         
314 }
315
316
317
318 static void close_stream_mem(v3_keyed_stream_t stream)
319 {
320     // nothing to do
321     return;
322 }
323
324
325 static v3_keyed_stream_key_t open_key_mem(v3_keyed_stream_t stream,
326                                           char *key)
327 {
328     struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
329     struct hashtable *s = mks->ht;
330
331     struct mem_stream *m;
332
333     m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
334
335     if (!m) { 
336         char *mykey = palacios_alloc(strlen(key)+1);
337
338         if (!mykey) { 
339             ERROR("cannot allocate copy of key for key %s\n",key);
340             return 0;
341         }
342
343         strcpy(mykey,key);
344
345         m = create_mem_stream();
346         
347         if (!m) { 
348             palacios_free(mykey);
349             ERROR("cannot allocate mem keyed stream for key %s\n",key);
350             return 0;
351         }
352
353         if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) {
354             destroy_mem_stream(m);
355             palacios_free(mykey);
356             ERROR("cannot insert mem keyed stream for key %s\n",key);
357             return 0;
358         }
359     }
360
361     reset_mem_stream(m);
362     return m;
363
364 }
365
366
367 static void preallocate_hint_key_mem(v3_keyed_stream_t stream,
368                                      char *key,
369                                      uint64_t size)
370 {
371     struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
372     struct hashtable *s = mks->ht;
373
374     struct mem_stream *m;
375
376     if (mks->ot != V3_KS_WR_ONLY) { 
377         return;
378     }
379
380     m = (struct mem_stream *) palacios_htable_search(s,(addr_t)key);
381
382     if (!m) {
383         char *mykey;
384         
385         mykey=palacios_alloc(strlen(key)+1);
386         
387         if (!mykey) { 
388             ERROR("cannot allocate key space for preallocte for key %s\n",key);
389             return;
390         }
391         
392         strcpy(mykey,key);
393        
394         m = create_mem_stream_internal(size);
395         
396         if (!m) { 
397             ERROR("cannot preallocate mem keyed stream for key %s\n",key);
398             return;
399         }
400
401         if (!palacios_htable_insert(s,(addr_t)mykey,(addr_t)m)) {
402             ERROR("cannot insert preallocated mem keyed stream for key %s\n",key);
403             destroy_mem_stream(m);
404             return;
405         }
406     } else {
407         if (m->data_max < size) { 
408             if (expand_mem_stream(m,size)) { 
409                 ERROR("cannot expand key for preallocation for key %s\n",key);
410                 return;
411             }
412         }
413     }
414
415     return;
416
417 }
418
419 static void close_key_mem(v3_keyed_stream_t stream, 
420                           v3_keyed_stream_key_t key)
421 {
422     // nothing to do
423     return;
424 }
425
426 static sint64_t write_key_mem(v3_keyed_stream_t stream, 
427                               v3_keyed_stream_key_t key,
428                               void *buf,
429                               sint64_t len)
430 {
431     struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
432     struct mem_stream *m = (struct mem_stream *) key;
433     uint32_t mylen;
434     uint32_t writelen;
435
436     if (mks->ot!=V3_KS_WR_ONLY) {
437         return -1;
438     }
439
440     if (len<0) { 
441         return -1;
442     }
443     
444     mylen = (uint32_t) len;
445
446     writelen=write_mem_stream(m,buf,mylen);
447
448     if (writelen!=mylen) { 
449         ERROR("failed to write all data for key\n");
450         return -1;
451     } else {
452         return (sint64_t)writelen;
453     }
454 }
455
456 static sint64_t read_key_mem(v3_keyed_stream_t stream, 
457                              v3_keyed_stream_key_t key,
458                              void *buf,
459                              sint64_t len)
460 {
461     struct mem_keyed_stream *mks = (struct mem_keyed_stream *) stream;
462     struct mem_stream *m = (struct mem_stream *) key;
463     uint32_t mylen;
464     uint32_t readlen;
465     
466     if (mks->ot!=V3_KS_RD_ONLY) {
467         return -1;
468     }
469
470     if (len<0) { 
471         return -1;
472     }
473     
474     mylen = (uint32_t) len;
475     
476     readlen=read_mem_stream(m,buf,mylen);
477     
478     if (readlen!=mylen) { 
479         ERROR("failed to read all data for key\n");
480         return -1;
481     } else {
482         return (sint64_t)readlen;
483     }
484 }
485
486
487 /***************************************************************************************************
488   File-based implementation  ("file:")
489 *************************************************************************************************/
490
491 /*
492   A file keyed stream contains the fd of the directory
493   and a path
494 */
495
496 struct file_keyed_stream {
497     int   stype;
498     v3_keyed_stream_open_t ot;
499     char  *path;
500 };
501
502 struct file_stream {
503     int   stype;
504     struct file *f;   // the opened file
505 };
506
507
508 static v3_keyed_stream_t open_stream_file(char *url,
509                                           v3_keyed_stream_open_t ot)
510 {
511     struct file_keyed_stream *fks;
512     struct nameidata nd;
513
514     if (strncasecmp(url,"file:",5)) { 
515         WARNING("illegitimate attempt to open file stream \"%s\"\n",url);
516         return 0;
517     }
518
519     fks = palacios_alloc(sizeof(struct file_keyed_stream));
520     
521     if (!fks) { 
522         ERROR("cannot allocate space for file stream\n");
523         return 0;
524     }
525
526     fks->path = (char*)palacios_alloc(strlen(url+5)+1);
527     
528     if (!(fks->path)) { 
529         ERROR("cannot allocate space for file stream\n");
530         palacios_free(fks);
531         return 0;
532     }
533     
534     strcpy(fks->path,url+5);
535     
536     fks->stype=STREAM_FILE;
537
538     fks->ot= ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
539
540     // Does the directory exist, and can we read/write it?
541    
542     if (path_lookup(fks->path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) { 
543
544         // directory does does not exist.  
545
546         if (ot==V3_KS_RD_ONLY || ot==V3_KS_WR_ONLY) { 
547
548             // we are not being asked to create it
549             ERROR("attempt to open %s, which does not exist\n",fks->path);
550             goto fail_out;
551
552         } else {
553
554             // We are being asked to create it
555
556             struct dentry *de;
557             int err;
558
559             // Find its parent
560             if (path_lookup(fks->path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) { 
561                 ERROR("attempt to create %s failed because its parent cannot be looked up\n",fks->path);
562                 goto fail_out;
563             }
564
565             // Can we write to the parent?
566
567             if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) { 
568                 ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",fks->path);
569                 goto fail_out;
570             }
571
572             // OK, we can, so let's create it
573
574             de = lookup_create(&nd,1);
575
576             if (IS_ERR(de)) { 
577                 ERROR("cannot allocate dentry\n");
578                 goto fail_out;
579             }
580
581             err = vfs_mkdir(nd.path.dentry->d_inode, de, 0700);
582
583             // lookup_create locks this for us!
584
585             mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
586
587             if (err) {
588                 ERROR("attempt to create %s failed because mkdir failed\n",fks->path);
589                 goto fail_out;
590             }
591
592             // now the directory should exist and have reasonable permissions
593             return (v3_keyed_stream_t) fks;
594         }
595     } 
596
597     
598     // we must be in V3_KS_RD_ONLY or V3_KS_WR_ONLY, 
599     // and the directory exists, so we must check the permissions
600
601     if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | (ot==V3_KS_RD_ONLY ? MAY_READ : MAY_WRITE))) {
602         ERROR("attempt to open %s, which has the wrong permissions\n",fks->path);
603         goto fail_out;
604     } else {
605         return (v3_keyed_stream_t) fks;
606     }
607
608
609  fail_out:
610     palacios_free(fks->path);
611     palacios_free(fks);
612     return 0;
613
614 }
615
616 static void close_stream_file(v3_keyed_stream_t stream)
617 {
618     struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
619     
620     palacios_free(fks->path);
621     palacios_free(fks);
622
623 }
624
625 static void preallocate_hint_key_file(v3_keyed_stream_t stream,
626                                       char *key,
627                                       uint64_t size)
628 {
629     return;
630 }
631
632 static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream,
633                                            char *key)
634 {
635     struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
636     struct file_stream *fs;
637     char *path;
638
639     // the path is the stream's path plus the key name
640     // file:/home/foo + "regext" => "/home/foo/regext"
641     path = (char *) palacios_alloc(strlen(fks->path)+strlen(key)+2);
642     if (!path) {                                
643         ERROR("cannot allocate file keyed stream for key %s\n",key);
644         return 0;
645     }
646     strcpy(path,fks->path);
647     strcat(path,"/");
648     strcat(path,key);
649     
650     fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream *));
651     
652     if (!fs) { 
653         ERROR("cannot allocate file keyed stream for key %s\n",key);
654         palacios_free(path);
655         return 0;
656     }
657
658     fs->stype=STREAM_FILE;
659
660     fs->f = filp_open(path,O_RDWR|O_CREAT,0600);
661     
662     if (IS_ERR(fs->f)) {
663         ERROR("cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key);
664         palacios_free(fs);
665         palacios_free(path);
666         return 0;
667     }
668
669     palacios_free(path);
670
671     return fs;
672 }
673
674
675 static void close_key_file(v3_keyed_stream_t stream, 
676                            v3_keyed_stream_key_t key)
677 {
678     struct file_stream *fs = (struct file_stream *) key;
679
680     filp_close(fs->f,NULL);
681
682     palacios_free(fs);
683 }
684
685 static sint64_t write_key_file(v3_keyed_stream_t stream, 
686                                v3_keyed_stream_key_t key,
687                                void *buf,
688                                sint64_t len)
689 {
690     struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
691     struct file_stream *fs = (struct file_stream *) key;
692     mm_segment_t old_fs;
693     ssize_t done, left, total;
694     
695     if (fks->ot!=V3_KS_WR_ONLY) { 
696         return -1;
697     }
698     
699     if (len<0) { 
700         return -1;
701     }
702
703     total=len;
704     left=len;
705
706     old_fs = get_fs();
707     set_fs(get_ds());
708
709     while (left>0) {
710         done = fs->f->f_op->write(fs->f, buf+(total-left), left, &(fs->f->f_pos));
711         if (done<=0) {
712             return -1;
713         } else {
714             left -= done;
715         }
716     }
717     set_fs(old_fs);
718
719     return len;
720 }
721
722
723
724 static sint64_t read_key_file(v3_keyed_stream_t stream, 
725                               v3_keyed_stream_key_t key,
726                               void *buf,
727                               sint64_t len)
728 {
729     struct file_keyed_stream *fks = (struct file_keyed_stream *) stream;
730     struct file_stream *fs = (struct file_stream *) key;
731     mm_segment_t old_fs;
732     ssize_t done, left, total;
733     
734     if (fks->ot!=V3_KS_RD_ONLY) { 
735         return -1;
736     }
737
738     if (len<0) { 
739         return -1;
740     }
741
742     total=len;
743     left=len;
744
745     old_fs = get_fs();
746     set_fs(get_ds());
747
748     while (left>0) {
749         done = fs->f->f_op->read(fs->f, buf+(total-left), left, &(fs->f->f_pos));
750         if (done<=0) {
751             return -1;
752         } else {
753             left -= done;
754         }
755     }
756     set_fs(old_fs);
757
758     return len;
759
760 }
761
762
763
764
765 /***************************************************************************************************
766   User implementation   ("user:")
767 *************************************************************************************************/
768
769
770 // List of all user keyed stream connections for the guest
771 struct user_keyed_streams {
772     spinlock_t lock;
773     struct list_head streams;
774 };
775
776
777 // A single keyed stream connection to user space
778 struct user_keyed_stream {
779     int stype;
780     v3_keyed_stream_open_t otype;
781
782     char *url;
783     spinlock_t lock;
784     int waiting;
785
786     wait_queue_head_t user_wait_queue;
787     wait_queue_head_t host_wait_queue;
788
789     struct palacios_user_keyed_stream_op *op;
790
791     struct list_head node;
792 };
793
794
795 //
796 // List of all of the user streams
797 //
798 static struct user_keyed_streams *user_streams;
799
800
801
802 static int resize_op(struct palacios_user_keyed_stream_op **op, uint64_t buf_len)
803 {
804     struct palacios_user_keyed_stream_op *old = *op;
805     struct palacios_user_keyed_stream_op *new;
806     
807     if (!old) {
808         new = palacios_alloc(sizeof(struct palacios_user_keyed_stream_op)+buf_len);
809         if (!new) { 
810             return -1;
811         } else {
812             new->len=sizeof(struct palacios_user_keyed_stream_op)+buf_len;
813             new->buf_len=buf_len;
814             *op=new;
815             return 0;
816         }
817     } else {
818         if ((old->len-sizeof(struct palacios_user_keyed_stream_op)) >= buf_len) { 
819             old->buf_len=buf_len;
820             return 0;
821         } else {
822             palacios_free(old);
823             *op = 0 ;
824             return resize_op(op,buf_len);
825         }
826     }
827 }
828
829 //
830 // The assumption is that we enter this with the stream locked
831 // and we will return with it locked;  additionally, the op structure
832 // will be overwritten with the response
833 // 
834 static int do_request_to_response(struct user_keyed_stream *s, unsigned long *flags)
835 {
836
837     if (s->waiting) {
838         ERROR("user keyed stream request attempted while one is already in progress on %s\n",s->url);
839         return -1;
840     }
841
842     // we are now waiting for a response
843     s->waiting = 1;
844
845     // release the stream
846     spin_unlock_irqrestore(&(s->lock), *flags);
847
848     // wake up anyone waiting on it
849     wake_up_interruptible(&(s->user_wait_queue));
850
851     // wait for someone to give us a response
852     while (wait_event_interruptible(s->host_wait_queue, (s->waiting == 0)) != 0) {}
853
854     // reacquire the lock for our called
855     spin_lock_irqsave(&(s->lock), *flags);
856
857     return 0;
858 }
859
860 //
861 // The assumption is that we enter this with the stream locked
862 // and we will return with it UNlocked
863 // 
864 static int do_response_to_request(struct user_keyed_stream *s, unsigned long *flags)
865 {
866
867     if (!(s->waiting)) {
868         ERROR("user keyed stream response while no request is in progress on %s\n",s->url);
869         return -1;
870     }
871
872     // we are now waiting for a request
873     s->waiting = 0;
874
875     // release the stream
876     spin_unlock_irqrestore(&(s->lock), *flags);
877
878     // wake up anyone waiting on it
879     wake_up_interruptible(&(s->host_wait_queue));
880     
881     return 0;
882 }
883
884
885
886 static unsigned int keyed_stream_poll_user(struct file *filp, poll_table *wait)
887 {
888     struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
889     unsigned long flags;
890     
891     if (!s) {
892         return POLLERR;
893     }
894     
895     spin_lock_irqsave(&(s->lock), flags);
896
897     if (s->waiting) {
898         spin_unlock_irqrestore(&(s->lock), flags);
899         return POLLIN | POLLRDNORM;
900     }
901
902     poll_wait(filp, &(s->user_wait_queue), wait);
903     
904     spin_unlock_irqrestore(&(s->lock), flags);
905
906     return 0;
907 }
908
909 static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsigned long arg)
910 {
911     void __user *argp = (void __user *)arg;
912     unsigned long flags;
913     uint64_t size;
914     
915     struct user_keyed_stream *s = (struct user_keyed_stream *) (filp->private_data);
916     
917     switch (ioctl) {
918
919         case V3_KSTREAM_REQUEST_SIZE_IOCTL:
920             
921             // inform request size
922             
923             spin_lock_irqsave(&(s->lock), flags);
924             
925             if (!(s->waiting)) {
926                 spin_unlock_irqrestore(&(s->lock), flags);
927                 return 0;
928             }
929
930             size =  sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
931             
932             if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) {
933                 spin_unlock_irqrestore(&(s->lock), flags);
934                 ERROR("palacios user key size request failed to copy data\n");
935                 return -EFAULT;
936             }
937             
938             spin_unlock_irqrestore(&(s->lock), flags);
939             
940             return 1;
941             
942             break;
943
944         case V3_KSTREAM_REQUEST_PULL_IOCTL: 
945                 
946             // pull the request
947             
948             spin_lock_irqsave(&(s->lock), flags);
949
950             if (!(s->waiting)) {
951                 spin_unlock_irqrestore(&(s->lock), flags);
952                 ERROR("palacios user key pull request when not waiting\n");
953                 return 0;
954             }
955
956             size =  sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
957
958
959             if (copy_to_user((void __user *) argp, s->op, size)) {
960                 spin_unlock_irqrestore(&(s->lock), flags);
961                 ERROR("palacios user key pull request failed to copy data\n");
962                 return -EFAULT;
963             }
964
965             spin_unlock_irqrestore(&(s->lock), flags);
966             
967             return 1;
968             
969          
970             break;
971
972     case V3_KSTREAM_RESPONSE_PUSH_IOCTL:
973
974         // push the response
975
976         spin_lock_irqsave(&(s->lock), flags);
977
978         if (!(s->waiting)) {
979             spin_unlock_irqrestore(&(s->lock), flags);
980             ERROR("palacios user key push response when not waiting\n");
981             return 0;
982         }
983         
984         if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) {
985             ERROR("palacios user key push response failed to copy size\n");
986             spin_unlock_irqrestore(&(s->lock), flags);
987             return -EFAULT;
988         }
989
990         if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) {
991             ERROR("unable to resize op in user key push response\n");
992             spin_unlock_irqrestore(&(s->lock), flags);
993             return -EFAULT;
994         }
995
996         if (copy_from_user(s->op, (void __user *) argp, size)) {
997             spin_unlock_irqrestore(&(s->lock), flags);
998             return -EFAULT;
999         }
1000
1001         do_response_to_request(s,&flags);
1002         // this will have unlocked s for us
1003
1004         return 1;
1005
1006         break;
1007         
1008     default:
1009         ERROR("unknown ioctl in user keyed stream\n");
1010
1011         return -EFAULT;
1012
1013         break;
1014         
1015     }
1016 }
1017
1018
1019 static int keyed_stream_release_user(struct inode *inode, struct file *filp)
1020 {
1021     struct user_keyed_stream *s = filp->private_data;
1022     unsigned long f1,f2;
1023
1024     spin_lock_irqsave(&(user_streams->lock),f1);
1025     spin_lock_irqsave(&(s->lock), f2);
1026
1027     list_del(&(s->node));
1028
1029     spin_unlock_irqrestore(&(s->lock), f2);
1030     spin_unlock_irqrestore(&(user_streams->lock), f1);
1031     
1032     palacios_free(s->url);
1033     palacios_free(s);
1034
1035     return 0;
1036 }
1037
1038 static struct file_operations user_keyed_stream_fops = {
1039     .poll = keyed_stream_poll_user,
1040     .compat_ioctl = keyed_stream_ioctl_user,
1041     .unlocked_ioctl = keyed_stream_ioctl_user,
1042     .release = keyed_stream_release_user,
1043 };
1044
1045
1046 /*
1047   user_keyed_streams are allocated on user connect, and deallocated on user release
1048   
1049   palacios-side opens and closes only manipulate the open type
1050 */
1051
1052 int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned long arg, void *priv_data)
1053 {
1054     int fd;
1055     unsigned long flags;
1056     char *url;
1057     uint64_t len;
1058     struct user_keyed_stream *s;
1059     
1060     if (!user_streams) { 
1061         ERROR("no user space keyed streams!\n");
1062         return -1;
1063     }
1064
1065     // get the url
1066     if (copy_from_user(&len,(void __user *)arg,sizeof(len))) { 
1067         ERROR("cannot copy url len from user\n");
1068         return -1;
1069     }
1070
1071     url = palacios_alloc(len);
1072     
1073     if (!url) { 
1074         ERROR("cannot allocate url for user keyed stream\n");
1075         return -1;
1076     }
1077
1078     if (copy_from_user(url,((void __user *)arg)+sizeof(len),len)) {
1079         ERROR("cannot copy url from user\n");
1080         return -1;
1081     }
1082     url[len-1]=0;
1083         
1084     
1085     // Check for duplicate handler
1086     spin_lock_irqsave(&(user_streams->lock), flags);
1087     list_for_each_entry(s, &(user_streams->streams), node) {
1088         if (!strncasecmp(url, s->url, len)) {
1089             ERROR("user keyed stream connection with url \"%s\" already exists\n", url);
1090             palacios_free(url);
1091             return -1;
1092         }
1093     }
1094     spin_unlock_irqrestore(&(user_streams->lock), flags);
1095     
1096     // Create connection
1097     s = palacios_alloc(sizeof(struct user_keyed_stream));
1098     
1099     if (!s) {
1100         ERROR("cannot allocate new user keyed stream for %s\n",url);
1101         palacios_free(url);
1102         return -1;
1103     }
1104     
1105     
1106     // Get file descriptor
1107     fd = anon_inode_getfd("v3-kstream", &user_keyed_stream_fops, s, 0);
1108
1109     if (fd < 0) {
1110         ERROR("cannot allocate file descriptor for new user keyed stream for %s\n",url);
1111         palacios_free(s);
1112         palacios_free(url);
1113         return -1;
1114     }
1115     
1116     memset(s, 0, sizeof(struct user_keyed_stream));
1117     
1118     s->stype=STREAM_USER;
1119     s->url=url;
1120     
1121     init_waitqueue_head(&(s->user_wait_queue));
1122     init_waitqueue_head(&(s->host_wait_queue));
1123     
1124     // Insert connection into list
1125     spin_lock_irqsave(&(user_streams->lock), flags);
1126     list_add(&(s->node), &(user_streams->streams));
1127     spin_unlock_irqrestore(&(user_streams->lock), flags);
1128     
1129     return fd;
1130 }
1131     
1132 static struct user_keyed_stream *keyed_stream_user_find(char *url)
1133 {
1134     unsigned long flags;
1135     struct user_keyed_stream *s;
1136     
1137     if (!user_streams) { 
1138         ERROR("no user space keyed streams available\n");
1139         return NULL;
1140     }
1141     
1142     spin_lock_irqsave(&(user_streams->lock), flags);
1143     list_for_each_entry(s, &(user_streams->streams), node) {
1144         if (!strcasecmp(url, s->url)) {
1145             spin_unlock_irqrestore(&(user_streams->lock), flags);
1146             return s;
1147         }
1148     }
1149     
1150     spin_unlock_irqrestore(&(user_streams->lock), flags);
1151     
1152     return NULL;
1153 }
1154     
1155     
1156 static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot)
1157 {
1158     unsigned long flags;
1159     struct user_keyed_stream *s;
1160     
1161     s = keyed_stream_user_find(url);
1162     
1163     if (!s) {
1164         ERROR("cannot open user stream %s as it does not exist yet\n",url);
1165         return NULL;
1166     }
1167
1168     spin_lock_irqsave(&(s->lock), flags);
1169
1170     if (s->waiting) {
1171         spin_unlock_irqrestore(&(s->lock), flags);
1172         ERROR("cannot open user stream %s as it is already in waiting state\n",url);
1173         return NULL;
1174     }
1175     
1176     s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
1177     
1178     spin_unlock_irqrestore(&(s->lock), flags);
1179     
1180     return s;
1181     
1182 }
1183     
1184 // close stream does not do anything.  Creation of the stream and its cleanup
1185 // are driven by the user side, not the palacios side
1186 // might eventually want to reference count this, though
1187 static void close_stream_user(v3_keyed_stream_t stream)
1188 {
1189     return;
1190 }
1191
1192 static void preallocate_hint_key_user(v3_keyed_stream_t stream,
1193                                       char *key,
1194                                       uint64_t size)
1195 {
1196     return;
1197 }
1198
1199
1200
1201
1202 static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
1203 {
1204     unsigned long flags;
1205     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1206     uint64_t   len = strlen(key)+1;
1207     void *user_key;
1208
1209     spin_lock_irqsave(&(s->lock), flags);
1210
1211
1212     if (resize_op(&(s->op),len)) {
1213         spin_unlock_irqrestore(&(s->lock),flags);
1214         ERROR("cannot resize op in opening key %s on user keyed stream %s\n",key,s->url);
1215         return NULL;
1216     }
1217
1218     s->op->type = PALACIOS_KSTREAM_OPEN_KEY;
1219     s->op->buf_len = len;
1220     strncpy(s->op->buf,key,len);
1221
1222     // enter with it locked
1223     if (do_request_to_response(s,&flags)) { 
1224         spin_unlock_irqrestore(&(s->lock),flags);
1225         ERROR("request/response handling failed\n");
1226         return NULL;
1227     }
1228     // return with it locked
1229
1230     user_key=s->op->user_key;
1231
1232     spin_unlock_irqrestore(&(s->lock),flags);
1233
1234     return user_key;
1235 }
1236
1237 static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
1238 {
1239     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1240     uint64_t   len = 0;
1241     unsigned long flags;
1242     
1243     spin_lock_irqsave(&(s->lock), flags);
1244
1245     if (resize_op(&(s->op),len)) {
1246         spin_unlock_irqrestore(&(s->lock),flags);
1247         ERROR("cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url);
1248         return;
1249     }
1250
1251     s->op->type = PALACIOS_KSTREAM_CLOSE_KEY;
1252     s->op->buf_len = len;
1253     s->op->user_key = key;
1254
1255     // enter with it locked
1256     if (do_request_to_response(s,&flags)) { 
1257         spin_unlock_irqrestore(&(s->lock),flags);
1258         ERROR("request/response handling failed\n");
1259         return;
1260     }
1261     // return with it locked
1262
1263     spin_unlock_irqrestore(&(s->lock),flags);
1264
1265     return;
1266 }
1267
1268
1269
1270 static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
1271                               void *buf, sint64_t rlen)
1272 {
1273
1274     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1275     uint64_t   len = 0 ;
1276     sint64_t   xfer;
1277     unsigned long flags;
1278
1279     spin_lock_irqsave(&(s->lock), flags);
1280
1281     if (s->otype != V3_KS_RD_ONLY) { 
1282         spin_unlock_irqrestore(&(s->lock),flags);
1283         ERROR("attempt to read key from stream that is not in read state on %s\n",s->url);
1284     }   
1285
1286     if (resize_op(&(s->op),len)) {
1287         spin_unlock_irqrestore(&(s->lock),flags);
1288         ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
1289         return -1;
1290     }
1291
1292     s->op->type = PALACIOS_KSTREAM_READ_KEY;
1293     s->op->buf_len = len ;
1294     s->op->xfer = rlen;
1295     s->op->user_key = key;
1296
1297     // enter with it locked
1298     if (do_request_to_response(s,&flags)) { 
1299         spin_unlock_irqrestore(&(s->lock),flags);
1300         ERROR("request/response handling failed\n");
1301         return -1;
1302     }
1303     // return with it locked
1304
1305
1306     if (s->op->xfer>0) { 
1307         memcpy(buf,s->op->buf,s->op->xfer);
1308     }
1309
1310     xfer=s->op->xfer;
1311
1312     spin_unlock_irqrestore(&(s->lock),flags);
1313
1314     return xfer;
1315 }
1316
1317
1318 static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key,
1319                                void *buf, sint64_t wlen)
1320 {
1321
1322     struct user_keyed_stream *s = (struct user_keyed_stream *) stream;
1323     struct palacios_user_keyed_stream_op *op;
1324     uint64_t   len = wlen ;
1325     sint64_t   xfer;
1326     unsigned long flags;
1327     
1328     spin_lock_irqsave(&(s->lock), flags);
1329
1330     if (s->otype != V3_KS_WR_ONLY) { 
1331         spin_unlock_irqrestore(&(s->lock),flags);
1332         ERROR("attempt to write key on stream that is not in write state on %s\n",s->url);
1333     }   
1334
1335     if (resize_op(&(s->op),len)) {
1336         spin_unlock_irqrestore(&(s->lock),flags);
1337         ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
1338         return -1;
1339     }
1340
1341     op = s->op;
1342
1343     s->op->type = PALACIOS_KSTREAM_WRITE_KEY;
1344     s->op->buf_len = len;
1345     s->op->xfer = wlen;
1346     s->op->user_key = key;
1347
1348     memcpy(s->op->buf,buf,wlen);
1349
1350     // enter with it locked
1351     if (do_request_to_response(s,&flags)) { 
1352         spin_unlock_irqrestore(&(s->lock),flags);
1353         ERROR("request/response handling failed\n");
1354         return -1;
1355     }
1356     // return with it locked
1357
1358     xfer=s->op->xfer;
1359
1360     spin_unlock_irqrestore(&(s->lock),flags);
1361
1362     return xfer;
1363 }
1364
1365
1366
1367 /****************************************************************************************
1368  *    Network-based implementation  ("net:")
1369  *****************************************************************************************/
1370
1371
1372 #define NET_MAX_KEY_LEN 128
1373
1374 struct net_keyed_stream {
1375     int stype;
1376     int ot;
1377     struct net_stream * ns;
1378 };
1379
1380 struct net_stream {
1381     int stype;
1382     struct socket *sock;
1383 };
1384
1385
1386 //ignore the arguments given here currently
1387 static struct net_stream * create_net_stream(void) 
1388 {
1389     struct net_stream * ns = NULL;
1390
1391     ns = palacios_alloc(sizeof(struct net_stream));
1392     
1393     if (!ns) { 
1394         ERROR("Cannot allocate a net_stream\n");
1395         return 0;
1396     }
1397
1398     memset(ns, 0, sizeof(struct net_stream));
1399
1400     ns->stype = STREAM_NETWORK;
1401
1402     return ns;
1403 }
1404
1405 static void close_socket(v3_keyed_stream_t stream)
1406 {
1407     struct net_keyed_stream *nks = (struct net_keyed_stream *) stream;
1408
1409     if (nks) { 
1410         struct net_stream *ns = nks->ns;
1411
1412         if (ns) {
1413             ns->sock->ops->release(ns->sock);
1414             palacios_free(ns);
1415             ERROR("Close Socket\n");
1416         }
1417         
1418         palacios_free(ns);
1419     }
1420 }
1421
1422
1423 static void close_stream_net(v3_keyed_stream_t stream)
1424 {
1425         close_socket(stream);
1426 }
1427
1428 static int connect_to_ip(struct net_stream *ns, int hostip, int port)
1429 {
1430     struct sockaddr_in client;
1431
1432     if (ns == NULL) {
1433         return -1;
1434     }
1435
1436     if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) { 
1437         ERROR("Cannot create accept socket\n");
1438         return -1;
1439     }
1440         
1441
1442     client.sin_family = AF_INET;
1443     client.sin_port = htons(port);
1444     client.sin_addr.s_addr = hostip;//in_aton(hostip);
1445
1446     return ns->sock->ops->connect(ns->sock, (struct sockaddr *)&client, sizeof(client), 0);
1447 }
1448
1449 static int send_msg(struct net_stream *ns,  char * buf, int len)
1450 {
1451     int left=len;
1452
1453     if (!ns) { 
1454         ERROR("Send message on null net_stream\n");
1455         return -1;
1456     }
1457
1458     if (!(ns->sock)) { 
1459         ERROR("Send message on net_stream without socket\n");
1460         return -1;
1461     }
1462
1463     while (left>0) {
1464
1465         struct msghdr msg;
1466         mm_segment_t oldfs;
1467         struct iovec iov;
1468         int err = 0;
1469         
1470
1471         msg.msg_flags = MSG_NOSIGNAL;//MSG_DONTWAIT;
1472         msg.msg_name = 0;
1473         msg.msg_namelen = 0;
1474         msg.msg_control = NULL;
1475         msg.msg_controllen = 0;
1476         msg.msg_iov = &iov;
1477         msg.msg_iovlen = 1;
1478
1479         iov.iov_base = (char *)&(buf[len-left]);
1480         iov.iov_len = (size_t)left;
1481
1482         oldfs = get_fs();
1483         set_fs(KERNEL_DS);
1484
1485         err = sock_sendmsg(ns->sock, &msg, (size_t)left);
1486
1487         set_fs(oldfs);
1488         
1489         if (err<0) {
1490             ERROR("Send msg error %d\n",err);
1491             return err;
1492         } else {
1493             left-=len;
1494         }
1495     }
1496
1497     return len;
1498 }
1499
1500
1501
1502 static int recv_msg(struct net_stream *ns, char * buf, int len)
1503 {
1504
1505     int left=len;
1506
1507     if (!ns) { 
1508         ERROR("Receive message on null net_stream\n");
1509         return -1;
1510     }
1511
1512     if (!(ns->sock)) { 
1513         ERROR("Receive  message on net_stream without socket\n");
1514         return -1;
1515     }
1516     
1517     
1518     while (left>0) {
1519         
1520         struct msghdr msg;
1521         mm_segment_t oldfs;
1522         struct iovec iov;
1523         int err;
1524         
1525         msg.msg_flags = 0;
1526         msg.msg_name = 0;
1527         msg.msg_namelen = 0;
1528         msg.msg_control = NULL;
1529         msg.msg_controllen = 0;
1530         msg.msg_iov = &iov;
1531         msg.msg_iovlen = 1;
1532         
1533         iov.iov_base = (void *)&(buf[len-left]);
1534         iov.iov_len = (size_t)left;
1535         
1536         oldfs = get_fs();
1537         set_fs(KERNEL_DS);
1538         
1539         err = sock_recvmsg(ns->sock, &msg, (size_t)left, 0);
1540         
1541         set_fs(oldfs);
1542         
1543         if (err<0) { 
1544             return err;
1545         } else {
1546             left -= err;
1547         }
1548     }
1549     return len;
1550 }
1551
1552 static struct net_stream * accept_once(struct net_stream * ns, const int port)
1553 {
1554     struct socket *accept_sock;
1555     struct sockaddr_in addr;
1556     int err;
1557     
1558     if (!ns) { 
1559         ERROR("Accept called on null net_stream\n");
1560         return 0;
1561     }
1562     
1563     if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&accept_sock)<0) { 
1564         ERROR("Cannot create accept socket\n"); 
1565         return NULL;
1566     }
1567     
1568
1569     addr.sin_family = AF_INET;
1570     addr.sin_port = htons(port);
1571     addr.sin_addr.s_addr = INADDR_ANY;
1572     
1573     err = accept_sock->ops->bind(accept_sock, (struct sockaddr *)&addr, sizeof(addr));
1574     
1575     if (err<0) {
1576         ERROR("Bind err: %d\n",err);
1577         return NULL;
1578     }
1579
1580     err = accept_sock->ops->listen(accept_sock,2);
1581     
1582     if (err<0) {
1583         ERROR("Listen err: %d\n",err);
1584         return NULL;
1585     }
1586     
1587     // Init the socket in the network strream
1588
1589     if (sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&(ns->sock))<0) { 
1590         ERROR("Cannot create socket\n");
1591         return NULL;
1592     }
1593     
1594     
1595     // Do the actual accept 
1596
1597     if (accept_sock->ops->accept(accept_sock,ns->sock,0)<0) {
1598         ERROR("accept failed");
1599         return NULL;
1600     }
1601     
1602     // close the accept socket
1603     accept_sock->ops->release(accept_sock);
1604     palacios_free(accept_sock);
1605
1606     return ns;
1607 }
1608
1609
1610 static struct v3_keyed_stream_t * open_stream_net(char * url,v3_keyed_stream_open_t ot)
1611 {
1612     struct net_keyed_stream * nks;
1613     int url_len;
1614     int i;
1615     int delimit[3];
1616     int k;
1617     char mode;
1618     int ip_len;
1619     int port_len;
1620
1621     nks = palacios_alloc(sizeof(struct net_keyed_stream)); 
1622
1623     if (!nks) { 
1624         ERROR("Could not allocate space in open_stream_net\n");
1625         return 0;
1626     }
1627     
1628     nks->ot = ot == V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
1629
1630     nks->stype = STREAM_NETWORK; 
1631
1632     nks->ns = create_net_stream();
1633     
1634     if (!(nks->ns)) { 
1635         ERROR("Could not create network stream\n");
1636         palacios_free(nks);
1637         return 0;
1638     }
1639
1640     url_len=strlen(url);
1641     k=0;
1642
1643
1644     for(i = 0; i < url_len;i++){
1645         if(url[i] == ':'){
1646             delimit[k] = i;
1647             k++;        
1648         }
1649     }
1650
1651     mode = url[delimit[0] + 1];
1652     ip_len = delimit[2] - delimit[1];
1653     port_len = url_len - delimit[2];
1654
1655
1656     {
1657         char ip[ip_len];
1658         char port[port_len];
1659         int host_ip;
1660         int host_port;
1661
1662
1663         strncpy(ip,url + delimit[1]+1,ip_len-1);
1664         ip[ip_len-1]='\0';
1665         
1666         host_ip = in_aton(ip);
1667         
1668         strncpy(port,url+ delimit[2]+1,port_len-1);
1669         port[port_len-1]='\0';
1670         
1671         host_port = simple_strtol(port,NULL,10);
1672
1673         INFO("ip is %s\n",ip); 
1674         INFO("host_ip is %x\n", host_ip);
1675         INFO("port is %s (%d)\n",port,host_port);
1676         
1677         if (mode == 'a'){
1678             // accept a request
1679             INFO("Accepting Connection on INADDR_ANY port:%d\n",host_port);
1680             nks->ns = accept_once(nks->ns, host_port);
1681         } else if (mode == 'c'){
1682             // call connect to ip
1683             INFO("Connecting to %s:%d\n",ip,host_port);
1684             connect_to_ip(nks->ns,host_ip, host_port);
1685         } else {
1686             ERROR("Mode not recognized\n");
1687             palacios_free(nks);
1688             return NULL;
1689         }
1690         
1691         return (v3_keyed_stream_t)nks;
1692     }
1693 }
1694
1695 static void preallocate_hint_key_net(v3_keyed_stream_t stream, char *key,uint64_t size)
1696 {
1697     //do nothing
1698 }
1699
1700 static v3_keyed_stream_key_t open_key_net(v3_keyed_stream_t stream,char *key)
1701 {
1702    struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
1703
1704    // reciever of the key name 
1705    if (nks->ot==V3_KS_WR_ONLY)
1706    {
1707        unsigned short keylen = strlen(key);
1708
1709        if (keylen>NET_MAX_KEY_LEN || keylen>=32768) { 
1710            ERROR("Key is too long\n");
1711            return NULL;
1712        }
1713
1714        {
1715            // on-stack allocation here demands that we
1716            // keep key length low...
1717            char msg[keylen+3];
1718            int next = 0;
1719            
1720            // Opening a key for writing sends a notice of the 
1721            // key length and the key name on the channel
1722            
1723            msg[next++]=keylen & 0xFF;
1724            msg[next]=(keylen>>8) & 0xFF;
1725            // Set flag bit
1726            msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will flip leading bit to 1
1727            
1728            strncpy(msg+2,key,keylen);  // will also copy trailing zero
1729            
1730            if (send_msg(nks->ns,msg,keylen+2) != keylen+2) { 
1731                ERROR("Unable to open key for writing on net_stream (send key len+name)\n");
1732                return NULL;
1733            }
1734        }
1735    }
1736
1737    if (nks->ot==V3_KS_RD_ONLY)   {
1738        char msg_info[2];
1739        int next = 0;
1740        int keylen = 0;
1741
1742        if (recv_msg(nks->ns,msg_info,2) != 2) { 
1743            ERROR("Unable to open key for reading on net_stream (recv key len)\n");
1744            return NULL;
1745        }
1746
1747        next = 0;
1748        keylen = 0;
1749
1750        keylen |= msg_info[next++];
1751
1752        if ((msg_info[next] & 0x80) != 0x80)  {
1753            ERROR("Flag bit not set on receive of key length\n");
1754            return NULL;
1755        } else {
1756            msg_info[next] &= 0x7F; // flip the msb back to zero (clear flag)
1757        }
1758        
1759        keylen |= msg_info[next]<<8;
1760
1761        if (keylen > NET_MAX_KEY_LEN) { 
1762            ERROR("Received key length is too big\n");
1763            return NULL;
1764        }
1765        
1766        {
1767            
1768            char msg[keylen+1];
1769            
1770            if (recv_msg(nks->ns,msg,keylen) != keylen) { 
1771                ERROR("Unable to receive key\n");
1772                return NULL;
1773            }
1774            msg[keylen]=0;
1775            
1776            if (strncmp(key,msg,keylen)!=0) {
1777                ERROR("Key mismatch in open_key_net - expect %s but got %s\n",key,msg);
1778                return NULL;
1779            }
1780        }
1781    }
1782    
1783    return (v3_keyed_stream_key_t)key;
1784 }
1785
1786 static void close_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t input_key)
1787 {
1788     char * key = (char*)input_key;
1789     struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
1790
1791     
1792     if (nks->ot==V3_KS_WR_ONLY) {
1793         unsigned short keylen = strlen(key);
1794
1795         if (keylen > NET_MAX_KEY_LEN || keylen>=32768) {
1796             ERROR("Key length too long in close_key_net\n");
1797             return;
1798         }
1799
1800         {
1801             char msg[keylen+3];
1802             int next = 0;
1803             
1804             msg[next++]=keylen & 0xFF;
1805             msg[next]=(keylen>>8) & 0xFF;
1806             // flag
1807             msg[next]=msg[next] | 0x80; // 0x80 is 128 and OR will filp leading bit to 1
1808             strncpy(msg+2,key,keylen); // will copy the zero
1809             msg[keylen+2]=0;
1810             if (send_msg(nks->ns,msg,keylen+2)!=keylen+2) { 
1811                 ERROR("Cannot send key on close_key_net\n");
1812                 return;
1813             }
1814         }
1815     }
1816     
1817     if (nks->ot==V3_KS_RD_ONLY)   {
1818         char msg_info[2];
1819         int next;
1820         int keylen;
1821         
1822         if (recv_msg(nks->ns,msg_info,2) != 2) { 
1823             ERROR("Cannot recv key length on close_key_net\n");
1824             return;
1825         }
1826         
1827         next = 0;
1828         keylen = 0;
1829         
1830         keylen |= msg_info[next++];
1831         
1832         if ((msg_info[next] & 0x80) != 0x80) {
1833             ERROR("Missing flag in close_key_net receive\n");
1834             return;
1835         } 
1836         
1837         msg_info[next] &= 0x7F; // flip the msb back to zero
1838         
1839         keylen |= msg_info[next]<<8;
1840         
1841         {
1842             char msg[keylen+1];
1843             
1844             if (recv_msg(nks->ns,msg,keylen)!=keylen) { 
1845                 ERROR("Did not receive all of key in close_key_net receive\n");
1846                 return;
1847             }
1848             
1849             msg[keylen]=0;
1850             
1851             if (strncmp(key,msg,keylen)!=0)  {
1852                 ERROR("Key mismatch in close_key_net - expect %s but got %s\n",key,msg);
1853                 return;
1854             }
1855         }
1856     }
1857 }
1858
1859 static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, void *buf, sint64_t len) 
1860 {
1861     struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
1862
1863     if (!buf) { 
1864         ERROR("Buf is NULL in write_key_net\n");
1865         return -1;
1866     }
1867
1868     if (len<0) {
1869         ERROR("len is negative in write_key_net\n");
1870         return -1;
1871     }
1872     
1873     if (!key){
1874        ERROR("write_key: key is NULL in write_key_net\n");
1875        return -1;
1876     }
1877     
1878     
1879     if (!nks)  {
1880         ERROR("nks is NULL in write_key_net\n");
1881         return -1;
1882     }
1883     
1884     if (nks->ot==V3_KS_WR_ONLY) {
1885         if (send_msg(nks->ns,(char*)(&len),sizeof(len))!=sizeof(len)) { 
1886             ERROR("Could not send data length in write_key_net\n");
1887             return -1;
1888         } 
1889         if (send_msg(nks->ns,buf,len)!=len) { 
1890             ERROR("Could not send data in write_key_net\n");
1891             return -1;
1892         }
1893     }  else {
1894         ERROR("Permission not correct in write_key_net\n");
1895         return -1;
1896     }
1897     
1898     return len;
1899 }
1900
1901
1902 static sint64_t read_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t key, void *buf, sint64_t len)
1903 {
1904     struct net_keyed_stream * nks = (struct net_keyed_stream *)stream;
1905
1906     if (!buf) {
1907         ERROR("Buf is NULL in read_key_net\n");
1908         return -1;
1909     }
1910     
1911     if(len<0) {
1912         ERROR("len is negative in read_key_net\n");
1913         return -1;
1914     }
1915     
1916     if (!key) {
1917         ERROR("read_key: key is NULL in read_key_net\n");
1918         return -1;
1919     }
1920
1921
1922     if (nks->ot==V3_KS_RD_ONLY) {
1923
1924         sint64_t slen;
1925            
1926         if (recv_msg(nks->ns,(char*)(&slen),sizeof(slen))!=sizeof(slen)) { 
1927             ERROR("Cannot receive data len in read_key_net\n");
1928             return -1;
1929         }
1930
1931         if (slen!=len) {
1932             ERROR("Data len expected does not matched data len decoded in read_key_net\n");
1933             return -1;
1934         }
1935
1936         if (recv_msg(nks->ns,buf,len)!=len) { 
1937             ERROR("Cannot recieve data in read_key_net\n");
1938             return -1;
1939         }
1940         
1941     } else {
1942         ERROR("Permissions incorrect for the stream in read_key_net\n");
1943         return -1;
1944     }
1945
1946     return len;
1947     
1948 }
1949
1950
1951 /***************************************************************************************************
1952   Generic interface
1953 *************************************************************************************************/
1954
1955 static v3_keyed_stream_t open_stream(char *url,
1956                                      v3_keyed_stream_open_t ot)
1957 {
1958     if (!strncasecmp(url,"mem:",4)) { 
1959         return open_stream_mem(url,ot);
1960     } else if (!strncasecmp(url,"file:",5)) { 
1961         return open_stream_file(url,ot);
1962     } else if (!strncasecmp(url,"user:",5)) { 
1963         return open_stream_user(url,ot);
1964     } else if(!strncasecmp(url,"net:",4)){
1965         return open_stream_net(url,ot);
1966     } else {
1967         ERROR("unsupported type in attempt to open keyed stream \"%s\"\n",url);
1968         return 0;
1969     }
1970 }
1971
1972 static void close_stream(v3_keyed_stream_t stream)
1973 {
1974     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1975     switch (gks->stype){ 
1976         case STREAM_MEM:
1977             return close_stream_mem(stream);
1978             break;
1979         case STREAM_FILE:
1980             return close_stream_file(stream);
1981             break;
1982         case STREAM_USER:
1983             return close_stream_user(stream);
1984             break;
1985         case STREAM_NETWORK:
1986             return close_stream_net(stream);
1987             break;
1988         default:
1989             ERROR("unknown stream type %d in close\n",gks->stype);
1990             break;
1991     }
1992 }
1993
1994 static void preallocate_hint_key(v3_keyed_stream_t stream,
1995                                  char *key,
1996                                  uint64_t size)
1997 {
1998     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
1999     switch (gks->stype){ 
2000         case STREAM_MEM:
2001             preallocate_hint_key_mem(stream,key,size);
2002             break;
2003         case STREAM_FILE:
2004             preallocate_hint_key_file(stream,key,size);
2005             break;
2006         case STREAM_USER:
2007             return preallocate_hint_key_user(stream,key,size);
2008             break;
2009         case STREAM_NETWORK:
2010             return preallocate_hint_key_net(stream,key,size);
2011             break;
2012         default:
2013             ERROR("unknown stream type %d in preallocate_hint_key\n",gks->stype);
2014             break;
2015     }
2016     return;
2017 }
2018
2019
2020 static v3_keyed_stream_key_t open_key(v3_keyed_stream_t stream,
2021                                       char *key)
2022 {
2023     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2024     switch (gks->stype){ 
2025         case STREAM_MEM:
2026             return open_key_mem(stream,key);
2027             break;
2028         case STREAM_FILE:
2029             return open_key_file(stream,key);
2030             break;
2031         case STREAM_USER:
2032             return open_key_user(stream,key);
2033             break;
2034         case STREAM_NETWORK:
2035             return open_key_net(stream, key);
2036             break;
2037         default:
2038             ERROR("unknown stream type %d in open_key\n",gks->stype);
2039             break;
2040     }
2041     return 0;
2042 }
2043
2044
2045 static void close_key(v3_keyed_stream_t stream, 
2046                       v3_keyed_stream_key_t key)
2047 {
2048     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2049     switch (gks->stype){ 
2050         case STREAM_MEM:
2051             return close_key_mem(stream,key);
2052             break;
2053         case STREAM_FILE:
2054             return close_key_file(stream,key);
2055             break;
2056         case STREAM_USER:
2057             return close_key_user(stream,key);
2058             break;
2059          case STREAM_NETWORK:
2060             return close_key_net(stream, key);
2061             break;      
2062         default:
2063             ERROR("unknown stream type %d in close_key\n",gks->stype);
2064             break;
2065     }
2066     // nothing to do
2067     return;
2068 }
2069
2070 static sint64_t write_key(v3_keyed_stream_t stream, 
2071                           v3_keyed_stream_key_t key,
2072                           void *buf,
2073                           sint64_t len)
2074 {
2075     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2076     switch (gks->stype){ 
2077         case STREAM_MEM:
2078             return write_key_mem(stream,key,buf,len);
2079             break;
2080         case STREAM_FILE:
2081             return write_key_file(stream,key,buf,len);
2082             break;
2083         case STREAM_USER:
2084             return write_key_user(stream,key,buf,len);
2085             break;
2086         case STREAM_NETWORK:
2087             return write_key_net(stream,key,buf,len);
2088             break;
2089         default:
2090             ERROR("unknown stream type %d in write_key\n",gks->stype);
2091             return -1;
2092             break;
2093     }
2094     return -1;
2095 }
2096
2097
2098 static sint64_t read_key(v3_keyed_stream_t stream, 
2099                          v3_keyed_stream_key_t key,
2100                          void *buf,
2101                          sint64_t len)
2102 {
2103     struct generic_keyed_stream *gks = (struct generic_keyed_stream *) stream;
2104     switch (gks->stype){ 
2105         case STREAM_MEM:
2106             return read_key_mem(stream,key,buf,len);
2107             break;
2108         case STREAM_FILE:
2109             return read_key_file(stream,key,buf,len);
2110             break;
2111         case STREAM_USER:
2112             return read_key_user(stream,key,buf,len);
2113             break;
2114         case STREAM_NETWORK:
2115             return read_key_net(stream,key,buf,len);
2116             break;
2117         default:
2118             ERROR("unknown stream type %d in read_key\n",gks->stype);
2119             return -1;
2120             break;
2121     }
2122     return -1;
2123 }
2124
2125
2126
2127
2128 /***************************************************************************************************
2129   Hooks to palacios and inititialization
2130 *************************************************************************************************/
2131
2132     
2133 static struct v3_keyed_stream_hooks hooks = {
2134     .open = open_stream,
2135     .close = close_stream,
2136     .preallocate_hint_key = preallocate_hint_key,
2137     .open_key = open_key,
2138     .close_key = close_key,
2139     .read_key = read_key,
2140     .write_key = write_key
2141 };
2142
2143
2144 static int init_keyed_streams( void )
2145 {
2146     mem_streams = palacios_create_htable(DEF_NUM_STREAMS,hash_func,hash_comp);
2147
2148     if (!mem_streams) { 
2149         ERROR("failed to allocated stream pool for in-memory streams\n");
2150         return -1;
2151     }
2152
2153     user_streams = palacios_alloc(sizeof(struct user_keyed_streams));
2154
2155     if (!user_streams) { 
2156         ERROR("failed to allocated list for user streams\n");
2157         return -1;
2158     }
2159
2160     INIT_LIST_HEAD(&(user_streams->streams));
2161     
2162     spin_lock_init(&(user_streams->lock));
2163
2164     V3_Init_Keyed_Streams(&hooks);
2165
2166     return 0;
2167
2168 }
2169
2170 static int deinit_keyed_streams( void )
2171 {
2172     palacios_free_htable(mem_streams,1,1);
2173
2174     palacios_free(user_streams);
2175
2176     WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n");
2177
2178     return 0;
2179 }
2180
2181
2182 static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data ) 
2183 {
2184     
2185     add_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT, keyed_stream_connect_user, 0);
2186     
2187     return 0;
2188 }
2189
2190
2191 static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data)
2192 {
2193
2194     return 0;
2195 }
2196
2197
2198
2199
2200 static struct linux_ext key_stream_ext = {
2201     .name = "KEYED_STREAM_INTERFACE",
2202     .init = init_keyed_streams,
2203     .deinit = deinit_keyed_streams,
2204     .guest_init = guest_init_keyed_streams,
2205     .guest_deinit = guest_deinit_keyed_streams, 
2206 };
2207
2208
2209 register_extension(&key_stream_ext);