summaryrefslogtreecommitdiff
path: root/source4/build/pidl
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-01-11 16:53:02 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:08:43 -0500
commitfae215266b6711b24f4893653b146751885e4e5f (patch)
treeaf13886f2431e1aa8a55a6da473e950dd3d5a053 /source4/build/pidl
parent90d65c2e85c8042391b8219eeaedd780e6eb3c7c (diff)
downloadsamba-fae215266b6711b24f4893653b146751885e4e5f.tar.gz
samba-fae215266b6711b24f4893653b146751885e4e5f.tar.bz2
samba-fae215266b6711b24f4893653b146751885e4e5f.zip
r4690: - add support for async rpc server replies
the backend should check for (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_MAY_ASYNC) then it's allowed to reply async then the backend should mark that call as async with dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; later it has to manualy set r->out.result and then send the reply by calling status = dcesrv_reply(p->dce_call); NOTE: that ncacn_np doesn't support async replies yet - implement an async version of echo_TestSleep - reenable the echo_TestSleep torture test (this need to be more strict when we have support for async ncacn_np) metze (This used to be commit f0a0dbeb25b034b1333078ca085999359f5f6209)
Diffstat (limited to 'source4/build/pidl')
-rw-r--r--source4/build/pidl/server.pm73
-rw-r--r--source4/build/pidl/stub.pm82
2 files changed, 120 insertions, 35 deletions
diff --git a/source4/build/pidl/server.pm b/source4/build/pidl/server.pm
index 5c70adf2af..e080bf5654 100644
--- a/source4/build/pidl/server.pm
+++ b/source4/build/pidl/server.pm
@@ -36,6 +36,29 @@ sub gen_dispatch_switch($)
} else {
pidl "\t\t$d->{NAME}(dce_call, mem_ctx, r2);\n";
}
+ pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n";
+ pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} will reply async\\n\"));\n";
+ pidl "\t\t}\n";
+ pidl "\t\tbreak;\n\t}\n";
+ $count++;
+ }
+}
+
+#####################################################
+# generate the switch statement for function reply
+sub gen_reply_switch($)
+{
+ my $data = shift;
+
+ my $count = 0;
+ foreach my $d (@{$data}) {
+ next if ($d->{TYPE} ne "FUNCTION");
+
+ pidl "\tcase $count: {\n";
+ pidl "\t\tstruct $d->{NAME} *r2 = r;\n";
+ pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n";
+ pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} replied async\\n\"));\n";
+ pidl "\t\t}\n";
pidl "\t\tif (DEBUGLEVEL > 10 && dce_call->fault_code == 0) {\n";
pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($d->{NAME}, NDR_OUT | NDR_SET_VALUES, r2);\n";
pidl "\t\t}\n";
@@ -47,7 +70,6 @@ sub gen_dispatch_switch($)
}
}
-
#####################################################################
# produce boilerplate code for a interface
sub Boilerplate_Iface($)
@@ -91,9 +113,7 @@ static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_C
}
*r = talloc_size(mem_ctx, dcerpc_table_$name.calls[opnum].struct_size);
- if (!*r) {
- return NT_STATUS_NO_MEMORY;
- }
+ NT_STATUS_HAVE_NO_MEMORY(*r);
/* unravel the NDR for the packet */
status = dcerpc_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r);
@@ -111,8 +131,6 @@ static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_C
{
uint16 opnum = dce_call->pkt.u.request.opnum;
- dce_call->fault_code = 0;
-
switch (opnum) {
";
gen_dispatch_switch($data);
@@ -132,6 +150,29 @@ pidl "
return NT_STATUS_OK;
}
+static NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
+{
+ uint16 opnum = dce_call->pkt.u.request.opnum;
+
+ switch (opnum) {
+";
+ gen_reply_switch($data);
+
+pidl "
+ default:
+ dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
+ break;
+ }
+
+ if (dce_call->fault_code != 0) {
+ dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
+ &dce_call->pkt.u.request.stub_and_verifier);
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, void *r)
{
NTSTATUS status;
@@ -147,14 +188,15 @@ static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_C
}
static const struct dcesrv_interface $name\_interface = {
- \"$name\",
- $uuid,
- $if_version,
- $name\__op_bind,
- $name\__op_unbind,
- $name\__op_ndr_pull,
- $name\__op_dispatch,
- $name\__op_ndr_push
+ .name = \"$name\",
+ .uuid = $uuid,
+ .if_version = $if_version,
+ .bind = $name\__op_bind,
+ .unbind = $name\__op_unbind,
+ .ndr_pull = $name\__op_ndr_pull,
+ .dispatch = $name\__op_dispatch,
+ .reply = $name\__op_reply,
+ .ndr_push = $name\__op_ndr_push
};
";
@@ -237,7 +279,7 @@ NTSTATUS dcerpc_server_$name\_init(void)
}
#####################################################################
-# parse a parsed IDL structure back into an IDL file
+# dcerpc server boilerplate from a parsed IDL structure
sub ParseInterface($)
{
my($interface) = shift;
@@ -270,4 +312,3 @@ sub ParseInterface($)
}
1;
-
diff --git a/source4/build/pidl/stub.pm b/source4/build/pidl/stub.pm
index d1448d467b..a9c938df63 100644
--- a/source4/build/pidl/stub.pm
+++ b/source4/build/pidl/stub.pm
@@ -2,6 +2,7 @@
# stub boilerplate generator
# Copyright jelmer@samba.org 2004
# Copyright tridge@samba.org 2003
+# Copyright metze@samba.org 2004
# released under the GNU GPL
package IdlStub;
@@ -39,25 +40,46 @@ sub gen_dispatch_switch($)
} else {
pidl "\t\tvtable->$d->{NAME}(iface, mem_ctx, r2);\n";
}
+ pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n";
+ pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} will reply async\\n\"));\n";
+ pidl "\t\t}\n";
+ pidl "\t\tbreak;\n\t}\n";
+ $count++;
+ }
+}
+
+#####################################################
+# generate the switch statement for function reply
+sub gen_reply_switch($)
+{
+ my $data = shift;
+
+ my $count = 0;
+ foreach my $d (@{$data}) {
+ next if ($d->{TYPE} ne "FUNCTION");
+
+ pidl "\tcase $count: {\n";
+ pidl "\t\tstruct $d->{NAME} *r2 = r;\n";
+ pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n";
+ pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} replied async\\n\"));\n";
+ pidl "\t\t}\n";
pidl "\t\tif (DEBUGLEVEL > 10 && dce_call->fault_code == 0) {\n";
pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($d->{NAME}, NDR_OUT | NDR_SET_VALUES, r2);\n";
pidl "\t\t}\n";
pidl "\t\tif (dce_call->fault_code != 0) {\n";
- pidl "\t\t\tDEBUG(2,(\"dcerpc_fault 0x%x in $d->{NAME}\\n\", dce_call->fault_code));\n";
+ pidl "\t\t\tDEBUG(2,(\"dcerpc_fault %s in $d->{NAME}\\n\", dcerpc_errstr(mem_ctx, dce_call->fault_code)));\n";
pidl "\t\t}\n";
pidl "\t\tbreak;\n\t}\n";
$count++;
}
}
-
#####################################################################
# produce boilerplate code for a interface
sub Boilerplate_Iface($)
{
my($interface) = shift;
my($data) = $interface->{DATA};
- my $count = 0;
my $name = $interface->{NAME};
my $uname = uc $name;
my $uuid = util::make_str($interface->{PROPERTIES}->{uuid});
@@ -76,7 +98,7 @@ static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct
static void $name\__op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
{
#ifdef DCESRV_INTERFACE_$uname\_UNBIND
- DCESRV_INTERFACE_$uname\_UNBIND(context,iface);
+ DCESRV_INTERFACE_$uname\_UNBIND(context, iface);
#else
return;
#endif
@@ -95,11 +117,9 @@ static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_C
}
*r = talloc_size(mem_ctx, dcerpc_table_$name.calls[opnum].struct_size);
- if (!*r) {
- return NT_STATUS_NO_MEMORY;
- }
+ NT_STATUS_HAVE_NO_MEMORY(*r);
- /* unravel the NDR for the packet */
+ /* unravel the NDR for the packet */
status = dcerpc_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r);
if (!NT_STATUS_IS_OK(status)) {
dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
@@ -118,8 +138,6 @@ static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_C
struct dcom_interface_p *iface = dcom_get_local_iface_p(&ipid);
const struct dcom_$name\_vtable *vtable = iface->vtable;
- dce_call->fault_code = 0;
-
switch (opnum) {
";
gen_dispatch_switch($data);
@@ -139,6 +157,29 @@ pidl "
return NT_STATUS_OK;
}
+static NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
+{
+ uint16 opnum = dce_call->pkt.u.request.opnum;
+
+ switch (opnum) {
+";
+ gen_reply_switch($data);
+
+pidl "
+ default:
+ dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
+ break;
+ }
+
+ if (dce_call->fault_code != 0) {
+ dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
+ &dce_call->pkt.u.request.stub_and_verifier);
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, void *r)
{
NTSTATUS status;
@@ -154,14 +195,15 @@ static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_C
}
static const struct dcesrv_interface $name\_interface = {
- \"$name\",
- $uuid,
- $if_version,
- $name\__op_bind,
- $name\__op_unbind,
- $name\__op_ndr_pull,
- $name\__op_dispatch,
- $name\__op_ndr_push
+ .name = \"$name\",
+ .uuid = $uuid,
+ .if_version = $if_version,
+ .bind = $name\__op_bind,
+ .unbind = $name\__op_unbind,
+ .ndr_pull = $name\__op_ndr_pull,
+ .dispatch = $name\__op_dispatch,
+ .reply = $name\__op_reply,
+ .ndr_push = $name\__op_ndr_push
};
";
@@ -243,10 +285,12 @@ NTSTATUS dcerpc_server_$name\_init(void)
";
}
+#####################################################################
+# dcom interface stub from a parsed IDL structure
sub ParseInterface($)
{
my($interface) = shift;
- my($data) = $interface->{DATA};
+ my($data) = $interface->{DATA};
my $count = 0;
$res = "";