Browse Source

Preliminary support for opening data-transfer interfaces

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
ff1222a8d3
4 changed files with 325 additions and 18 deletions
  1. 144
    0
      src/core/open.c
  2. 64
    12
      src/core/xfer.c
  3. 81
    0
      src/include/gpxe/open.h
  4. 36
    6
      src/include/gpxe/xfer.h

+ 144
- 0
src/core/open.c View File

@@ -0,0 +1,144 @@
1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdarg.h>
20
+#include <string.h>
21
+#include <errno.h>
22
+#include <gpxe/xfer.h>
23
+#include <gpxe/uri.h>
24
+#include <gpxe/socket.h>
25
+#include <gpxe/open.h>
26
+
27
+/** @file
28
+ *
29
+ * Data transfer interface opening
30
+ *
31
+ */
32
+
33
+/** Registered URI openers */
34
+static struct uri_opener uri_openers[0]
35
+	__table_start ( struct uri_opener, uri_openers );
36
+static struct uri_opener uri_openers_end[0]
37
+	__table_end ( struct uri_opener, uri_openers );
38
+
39
+/** Registered socket openers */
40
+static struct socket_opener socket_openers[0]
41
+	__table_start ( struct socket_opener, socket_openers );
42
+static struct socket_opener socket_openers_end[0]
43
+	__table_end ( struct socket_opener, socket_openers );
44
+
45
+/**
46
+ * Open URI
47
+ *
48
+ * @v xfer		Data-transfer interface
49
+ * @v uri_string	URI string (e.g. "http://etherboot.org/kernel")
50
+ * @ret rc		Return status code
51
+ */
52
+int open_uri ( struct xfer_interface *xfer, const char *uri_string ) {
53
+	struct uri *uri;
54
+	struct uri_opener *opener;
55
+
56
+	DBGC ( xfer, "XFER %p opening URI %s\n", xfer, uri_string );
57
+
58
+	uri = parse_uri ( uri_string );
59
+	if ( ! uri )
60
+		return -ENOMEM;
61
+
62
+	for ( opener = uri_openers ; opener < uri_openers_end ; opener++ ) {
63
+		if ( strcmp ( uri->scheme, opener->scheme ) == 0 ) {
64
+			return opener->open ( xfer, uri );
65
+		}
66
+	}
67
+
68
+	DBGC ( xfer, "XFER %p attempted to open unsupported URI scheme "
69
+	       "\"%s\"\n", xfer, uri->scheme );
70
+	free_uri ( uri );
71
+	return -ENOTSUP;
72
+}
73
+
74
+/**
75
+ * Open socket
76
+ *
77
+ * @v xfer		Data-transfer interface
78
+ * @v domain		Communication domain (e.g. PF_INET)
79
+ * @v type		Communication semantics (e.g. SOCK_STREAM)
80
+ */
81
+int open_socket ( struct xfer_interface *xfer,
82
+		  int domain, int type, struct sockaddr *sa ) {
83
+	struct socket_opener *opener;
84
+
85
+	DBGC ( xfer, "XFER %p opening (%s,%s) socket\n", xfer,
86
+	       socket_domain_name ( domain ), socket_type_name ( type ) );
87
+
88
+	for ( opener = socket_openers; opener < socket_openers_end; opener++ ){
89
+		if ( ( opener->domain == domain ) &&
90
+		     ( opener->type == type ) ) {
91
+			return opener->open ( xfer, sa );
92
+		}
93
+	}
94
+
95
+	DBGC ( xfer, "XFER %p attempted to open unsupported socket type "
96
+	       "(%s,%s)\n", xfer, socket_domain_name ( domain ),
97
+	       socket_type_name ( type ) );
98
+	return -ENOTSUP;
99
+}
100
+
101
+/**
102
+ * Open location
103
+ *
104
+ * @v xfer		Data-transfer interface
105
+ * @v type		Location type
106
+ * @v args		Remaining arguments depend upon location type
107
+ * @ret rc		Return status code
108
+ */
109
+int vopen ( struct xfer_interface *xfer, int type, va_list args ) {
110
+	switch ( type ) {
111
+	case LOCATION_URI: {
112
+		const char *uri_string = va_arg ( args, const char * );
113
+
114
+		return open_uri ( xfer, uri_string ); }
115
+	case LOCATION_SOCKET: {
116
+		int domain = va_arg ( args, int );
117
+		int type = va_arg ( args, int );
118
+		struct sockaddr *sa = va_arg ( args, struct sockaddr * );
119
+
120
+		return open_socket ( xfer, domain, type, sa ); }
121
+	default:
122
+		DBGC ( xfer, "XFER %p attempted to open unsupported location "
123
+		       "type %d\n", xfer, type );
124
+		return -ENOTSUP;
125
+	}
126
+}
127
+
128
+/**
129
+ * Open location
130
+ *
131
+ * @v xfer		Data-transfer interface
132
+ * @v type		Location type
133
+ * @v ...		Remaining arguments depend upon location type
134
+ * @ret rc		Return status code
135
+ */
136
+int open ( struct xfer_interface *xfer, int type, ... ) {
137
+	va_list args;
138
+	int rc;
139
+
140
+	va_start ( args, type );
141
+	rc = vopen ( xfer, type, args );
142
+	va_end ( args );
143
+	return rc;
144
+}

+ 64
- 12
src/core/xfer.c View File

@@ -26,6 +26,38 @@
26 26
  *
27 27
  */
28 28
 
29
+/**
30
+ * Send redirection event
31
+ *
32
+ * @v xfer		Data-transfer interface
33
+ * @v type		New location type
34
+ * @v args		Remaining arguments depend upon location type
35
+ * @ret rc		Return status code
36
+ */
37
+int vredirect ( struct xfer_interface *xfer, int type, va_list args ) {
38
+	struct xfer_interface *dest = xfer_dest ( xfer );
39
+
40
+	return dest->op->vredirect ( dest, type, args );
41
+}
42
+
43
+/**
44
+ * Send redirection event
45
+ *
46
+ * @v xfer		Data-transfer interface
47
+ * @v type		New location type
48
+ * @v ...		Remaining arguments depend upon location type
49
+ * @ret rc		Return status code
50
+ */
51
+int redirect ( struct xfer_interface *xfer, int type, ... ) {
52
+	va_list args;
53
+	int rc;
54
+
55
+	va_start ( args, type );
56
+	rc = vredirect ( xfer, type, args );
57
+	va_end ( args );
58
+	return rc;
59
+}
60
+
29 61
 /**
30 62
  * Deliver datagram
31 63
  *
@@ -36,14 +68,35 @@
36 68
 int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
37 69
 	struct xfer_interface *dest = xfer_dest ( xfer );
38 70
 
39
-	return dest->op->deliver ( dest, xfer, iobuf );
71
+	return dest->op->deliver ( dest, iobuf );
72
+}
73
+
74
+/**
75
+ * Deliver datagram as raw data
76
+ *
77
+ * @v xfer		Data-transfer interface
78
+ * @v iobuf		Datagram I/O buffer
79
+ * @ret rc		Return status code
80
+ */
81
+int deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ) {
82
+	struct xfer_interface *dest = xfer_dest ( xfer );
83
+
84
+	return dest->op->deliver_raw ( dest, data, len );
40 85
 }
41 86
 
87
+/****************************************************************************
88
+ *
89
+ * Helper methods
90
+ *
91
+ * These functions are designed to be used as methods in the
92
+ * xfer_interface_operations table.
93
+ *
94
+ */
95
+
42 96
 /**
43 97
  * Deliver datagram as raw data
44 98
  *
45 99
  * @v xfer		Data-transfer interface
46
- * @v src		Source interface
47 100
  * @v iobuf		Datagram I/O buffer
48 101
  * @ret rc		Return status code
49 102
  *
@@ -51,12 +104,10 @@ int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
51 104
  * data transfer interfaces that prefer to handle raw data.
52 105
  */
53 106
 int deliver_as_raw ( struct xfer_interface *xfer,
54
-		     struct xfer_interface *src,
55 107
 		     struct io_buffer *iobuf ) {
56 108
 	int rc;
57 109
 
58
-	rc = xfer->op->deliver_raw ( xfer, src, iobuf->data,
59
-				     iob_len ( iobuf ) );
110
+	rc = xfer->op->deliver_raw ( xfer, iobuf->data, iob_len ( iobuf ) );
60 111
 	free_iob ( iobuf );
61 112
 	return rc;
62 113
 }
@@ -65,7 +116,6 @@ int deliver_as_raw ( struct xfer_interface *xfer,
65 116
  * Deliver datagram as I/O buffer
66 117
  *
67 118
  * @v xfer		Data-transfer interface
68
- * @v src		Source interface
69 119
  * @v data		Data buffer
70 120
  * @v len		Length of data buffer
71 121
  * @ret rc		Return status code
@@ -74,32 +124,34 @@ int deliver_as_raw ( struct xfer_interface *xfer,
74 124
  * for data transfer interfaces that prefer to handle I/O buffers.
75 125
  */
76 126
 int deliver_as_iobuf ( struct xfer_interface *xfer,
77
-		       struct xfer_interface *src,
78 127
 		       const void *data, size_t len ) {
79 128
 	struct io_buffer *iobuf;
80 129
 
81
-#warning "Do we need interface-specific I/O buffer allocation?"
82 130
 	iobuf = alloc_iob ( len );
83 131
 	if ( ! iobuf )
84 132
 		return -ENOMEM;
85 133
 
86 134
 	memcpy ( iob_put ( iobuf, len ), data, len );
87
-	return xfer->op->deliver ( xfer, src, iobuf );
135
+	return xfer->op->deliver ( xfer, iobuf );
88 136
 }
89 137
 
138
+/****************************************************************************
139
+ *
140
+ * Null data transfer interface
141
+ *
142
+ */
143
+
90 144
 /**
91 145
  * Null deliver datagram as raw data
92 146
  *
93 147
  * @v xfer		Data-transfer interface
94
- * @v src		Source interface
95 148
  * @v data		Data buffer
96 149
  * @v len		Length of data buffer
97 150
  * @ret rc		Return status code
98 151
  */
99 152
 static int null_deliver_raw ( struct xfer_interface *xfer,
100
-			      struct xfer_interface *src,
101 153
 			      const void *data __unused, size_t len ) {
102
-	DBGC ( src, "XFER %p->%p %zd bytes delivered %s\n", src, xfer, len,
154
+	DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len,
103 155
 	       ( ( xfer == &null_xfer ) ?
104 156
 		 "before connection" : "after termination" ) );
105 157
 	return -EPIPE;

+ 81
- 0
src/include/gpxe/open.h View File

@@ -0,0 +1,81 @@
1
+#ifndef _GPXE_OPEN_H
2
+#define _GPXE_OPEN_H
3
+
4
+/** @file
5
+ *
6
+ * Data transfer interface opening
7
+ *
8
+ */
9
+
10
+#include <gpxe/tables.h>
11
+
12
+struct xfer_interface;
13
+struct uri;
14
+struct sockaddr;
15
+
16
+/** Location types */
17
+enum {
18
+	/** Location is a URI string
19
+	 *
20
+	 * Parameter list for open() is:
21
+	 *
22
+	 * const char *uri_string;
23
+	 */
24
+	LOCATION_URI = 1,
25
+	/** Location is a socket
26
+	 *
27
+	 * Parameter list for open() is:
28
+	 *
29
+	 * 
30
+	 */
31
+	LOCATION_SOCKET,
32
+};
33
+
34
+/** A URI opener */
35
+struct uri_opener {
36
+	/** URI protocol name
37
+	 *
38
+	 * This is the "scheme" portion of the URI, e.g. "http" or
39
+	 * "file".
40
+	 */
41
+	const char *scheme;
42
+	/** Open URI
43
+	 *
44
+	 * @v xfer		Data-transfer interface
45
+	 * @v uri		URI
46
+	 * @ret rc		Return status code
47
+	 *
48
+	 * This method takes ownership of the URI structure, and is
49
+	 * responsible for eventually calling free_uri().
50
+	 */
51
+	int ( * open ) ( struct xfer_interface *xfer, struct uri *uri );
52
+};
53
+
54
+/** Register a URI opener */
55
+#define __uri_opener __table ( struct uri_opener, uri_openers, 01 )
56
+
57
+/** A socket opener */
58
+struct socket_opener {
59
+	/** Communication domain (e.g. PF_INET) */
60
+	int domain;
61
+	/** Communication semantics (e.g. SOCK_STREAM) */
62
+	int type;
63
+	/** Open socket
64
+	 *
65
+	 * @v xfer		Data-transfer interface
66
+	 * @v sa		Socket address
67
+	 * @ret rc		Return status code
68
+	 */
69
+	int ( * open ) ( struct xfer_interface *xfer, struct sockaddr *sa );
70
+};
71
+
72
+/** Register a socket opener */
73
+#define __socket_opener __table ( struct socket_opener, socket_openers, 01 )
74
+
75
+extern int open_uri ( struct xfer_interface *xfer, const char *uri_string );
76
+extern int open_socket ( struct xfer_interface *xfer,
77
+			 int domain, int type, struct sockaddr *sa );
78
+extern int vopen ( struct xfer_interface *xfer, int type, va_list args );
79
+extern int open ( struct xfer_interface *xfer, int type, ... );
80
+
81
+#endif /* _GPXE_OPEN_H */

+ 36
- 6
src/include/gpxe/xfer.h View File

@@ -8,6 +8,7 @@
8 8
  */
9 9
 
10 10
 #include <stddef.h>
11
+#include <stdarg.h>
11 12
 #include <gpxe/interface.h>
12 13
 #include <gpxe/iobuf.h>
13 14
 
@@ -15,10 +16,38 @@ struct xfer_interface;
15 16
 
16 17
 /** Data transfer interface operations */
17 18
 struct xfer_interface_operations {
19
+
20
+	/* Missing features:
21
+	 *
22
+	 * notification of non-close status - e.g. connected/opened, ...
23
+	 *
24
+	 * seek
25
+	 *
26
+	 * prompt for data delivery
27
+	 *
28
+	 * I/O buffer preparation
29
+	 *
30
+	 */
31
+
32
+
33
+	/** Close interface
34
+	 *
35
+	 * @v xfer		Data-transfer interface
36
+	 * @v rc		Reason for close
37
+	 */
38
+	void ( * close ) ( struct xfer_interface *xfer, int rc );
39
+	/** Redirect to new location
40
+	 *
41
+	 * @v xfer		Data-transfer interface
42
+	 * @v type		New location type
43
+	 * @v args		Remaining arguments depend upon location type
44
+	 * @ret rc		Return status code
45
+	 */
46
+	int ( * vredirect ) ( struct xfer_interface *xfer, int type,
47
+			      va_list args );
18 48
 	/** Deliver datagram
19 49
 	 *
20 50
 	 * @v xfer		Data-transfer interface
21
-	 * @v src		Source interface
22 51
 	 * @v iobuf		Datagram I/O buffer
23 52
 	 * @ret rc		Return status code
24 53
 	 *
@@ -27,12 +56,10 @@ struct xfer_interface_operations {
27 56
 	 * deliver_as_raw().
28 57
 	 */
29 58
 	int ( * deliver ) ( struct xfer_interface *xfer,
30
-			    struct xfer_interface *src,
31 59
 			    struct io_buffer *iobuf );
32 60
 	/** Deliver datagram as raw data
33 61
 	 *
34 62
 	 * @v xfer		Data-transfer interface
35
-	 * @v src		Source interface
36 63
 	 * @v data		Data buffer
37 64
 	 * @v len		Length of data buffer
38 65
 	 * @ret rc		Return status code
@@ -42,7 +69,6 @@ struct xfer_interface_operations {
42 69
 	 * deliver_as_iobuf().
43 70
 	 */
44 71
 	int ( * deliver_raw ) ( struct xfer_interface *xfer,
45
-				struct xfer_interface *src,
46 72
 				const void *data, size_t len );
47 73
 };
48 74
 
@@ -57,11 +83,15 @@ struct xfer_interface {
57 83
 extern struct xfer_interface null_xfer;
58 84
 extern struct xfer_interface_operations null_xfer_ops;
59 85
 
86
+extern int vredirect ( struct xfer_interface *xfer, int type, va_list args );
87
+extern int redirect ( struct xfer_interface *xfer, int type, ... );
88
+extern int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf );
89
+extern int deliver_raw ( struct xfer_interface *xfer,
90
+			 const void *data, size_t len );
91
+
60 92
 extern int deliver_as_raw ( struct xfer_interface *xfer,
61
-			    struct xfer_interface *src,
62 93
 			    struct io_buffer *iobuf );
63 94
 extern int deliver_as_iobuf ( struct xfer_interface *xfer,
64
-			      struct xfer_interface *src,
65 95
 			      const void *data, size_t len );
66 96
 
67 97
 /**

Loading…
Cancel
Save