@@ -147,6 +147,11 @@ pub struct NetworkState {
147147}
148148
149149impl NetworkState {
150+ /// Create network state for a single WASM execution.
151+ ///
152+ /// The policy is validated and then enforced by every host call. All host
153+ /// functions share the same counters and audit logger, providing a single
154+ /// enforcement surface for HTTP and DNS access.
150155 pub fn new (
151156 policy : NetworkPolicy ,
152157 audit_logger : Option < Arc < dyn NetworkAuditLogger > > ,
@@ -218,6 +223,11 @@ impl NetworkState {
218223 & mut self ,
219224 request : HttpRequest ,
220225 ) -> Result < HttpResponse , NetworkError > {
226+ if !self . policy . allow_internet {
227+ self . audit_denial ( "http_request denied: network disabled" ) ;
228+ return Err ( NetworkError :: NetworkDisabled ) ;
229+ }
230+
221231 self . ensure_request_budget ( ) ?;
222232
223233 if let Err ( e) = self . validate_http_request ( & request) {
@@ -277,6 +287,11 @@ impl NetworkState {
277287 }
278288
279289 pub fn handle_dns_request ( & mut self , request : DnsRequest ) -> Result < DnsResponse , NetworkError > {
290+ if !self . policy . allow_internet {
291+ self . audit_denial ( "dns_lookup denied: network disabled" ) ;
292+ return Err ( NetworkError :: NetworkDisabled ) ;
293+ }
294+
280295 self . ensure_dns_budget ( ) ?;
281296
282297 if let Err ( e) = self
@@ -522,33 +537,39 @@ fn handle_http_request(
522537 resp_ptr : i32 ,
523538 resp_len : i32 ,
524539) -> i32 {
540+ let enforcement = "http_request" ;
525541 let request_bytes = match read_memory ( caller, req_ptr, req_len) {
526542 Ok ( bytes) => bytes,
527543 Err ( err) => {
544+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host memory read failed" ) ;
528545 return write_result :: < HttpResponse > (
529546 caller,
530547 resp_ptr,
531548 resp_len,
532549 Err ( NetworkError :: HttpFailure ( err) ) ,
533- )
550+ ) ;
534551 }
535552 } ;
536553
537554 let request = match bincode:: deserialize :: < HttpRequest > ( & request_bytes) {
538555 Ok ( req) => req,
539556 Err ( err) => {
557+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host request decode failed" ) ;
540558 return write_result :: < HttpResponse > (
541559 caller,
542560 resp_ptr,
543561 resp_len,
544562 Err ( NetworkError :: HttpFailure ( format ! (
545563 "invalid http request payload: {err}"
546564 ) ) ) ,
547- )
565+ ) ;
548566 }
549567 } ;
550568
551569 let result = caller. data_mut ( ) . network_state . handle_http_request ( request) ;
570+ if let Err ( ref err) = result {
571+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host request denied" ) ;
572+ }
552573 write_result ( caller, resp_ptr, resp_len, result)
553574}
554575
@@ -559,29 +580,32 @@ fn handle_http_get(
559580 resp_ptr : i32 ,
560581 resp_len : i32 ,
561582) -> i32 {
583+ let enforcement = "http_get" ;
562584 let request_bytes = match read_memory ( caller, req_ptr, req_len) {
563585 Ok ( bytes) => bytes,
564586 Err ( err) => {
587+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host memory read failed" ) ;
565588 return write_result :: < HttpResponse > (
566589 caller,
567590 resp_ptr,
568591 resp_len,
569592 Err ( NetworkError :: HttpFailure ( err) ) ,
570- )
593+ ) ;
571594 }
572595 } ;
573596
574597 let request = match bincode:: deserialize :: < HttpGetRequest > ( & request_bytes) {
575598 Ok ( req) => req,
576599 Err ( err) => {
600+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host request decode failed" ) ;
577601 return write_result :: < HttpResponse > (
578602 caller,
579603 resp_ptr,
580604 resp_len,
581605 Err ( NetworkError :: HttpFailure ( format ! (
582606 "invalid http get payload: {err}"
583607 ) ) ) ,
584- )
608+ ) ;
585609 }
586610 } ;
587611
@@ -593,6 +617,9 @@ fn handle_http_get(
593617 } ;
594618
595619 let result = caller. data_mut ( ) . network_state . handle_http_request ( request) ;
620+ if let Err ( ref err) = result {
621+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host request denied" ) ;
622+ }
596623 write_result ( caller, resp_ptr, resp_len, result)
597624}
598625
@@ -603,29 +630,32 @@ fn handle_http_post(
603630 resp_ptr : i32 ,
604631 resp_len : i32 ,
605632) -> i32 {
633+ let enforcement = "http_post" ;
606634 let request_bytes = match read_memory ( caller, req_ptr, req_len) {
607635 Ok ( bytes) => bytes,
608636 Err ( err) => {
637+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host memory read failed" ) ;
609638 return write_result :: < HttpResponse > (
610639 caller,
611640 resp_ptr,
612641 resp_len,
613642 Err ( NetworkError :: HttpFailure ( err) ) ,
614- )
643+ ) ;
615644 }
616645 } ;
617646
618647 let request = match bincode:: deserialize :: < HttpPostRequest > ( & request_bytes) {
619648 Ok ( req) => req,
620649 Err ( err) => {
650+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host request decode failed" ) ;
621651 return write_result :: < HttpResponse > (
622652 caller,
623653 resp_ptr,
624654 resp_len,
625655 Err ( NetworkError :: HttpFailure ( format ! (
626656 "invalid http post payload: {err}"
627657 ) ) ) ,
628- )
658+ ) ;
629659 }
630660 } ;
631661
@@ -637,6 +667,9 @@ fn handle_http_post(
637667 } ;
638668
639669 let result = caller. data_mut ( ) . network_state . handle_http_request ( request) ;
670+ if let Err ( ref err) = result {
671+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host request denied" ) ;
672+ }
640673 write_result ( caller, resp_ptr, resp_len, result)
641674}
642675
@@ -647,33 +680,39 @@ fn handle_dns_request(
647680 resp_ptr : i32 ,
648681 resp_len : i32 ,
649682) -> i32 {
683+ let enforcement = "dns_resolve" ;
650684 let request_bytes = match read_memory ( caller, req_ptr, req_len) {
651685 Ok ( bytes) => bytes,
652686 Err ( err) => {
687+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host memory read failed" ) ;
653688 return write_result :: < DnsResponse > (
654689 caller,
655690 resp_ptr,
656691 resp_len,
657692 Err ( NetworkError :: DnsFailure ( err) ) ,
658- )
693+ ) ;
659694 }
660695 } ;
661696
662697 let request = match bincode:: deserialize :: < DnsRequest > ( & request_bytes) {
663698 Ok ( req) => req,
664699 Err ( err) => {
700+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host request decode failed" ) ;
665701 return write_result :: < DnsResponse > (
666702 caller,
667703 resp_ptr,
668704 resp_len,
669705 Err ( NetworkError :: DnsFailure ( format ! (
670706 "invalid dns request payload: {err}"
671707 ) ) ) ,
672- )
708+ ) ;
673709 }
674710 } ;
675711
676712 let result = caller. data_mut ( ) . network_state . handle_dns_request ( request) ;
713+ if let Err ( ref err) = result {
714+ warn ! ( challenge_id = %caller. data( ) . challenge_id, validator_id = %caller. data( ) . validator_id, function = enforcement, error = %err, "host request denied" ) ;
715+ }
677716 write_result ( caller, resp_ptr, resp_len, result)
678717}
679718
0 commit comments